| 35 | } |
| 36 | |
| 37 | void BasicPitch::transcribeToMIDI(float* inAudio, int inNumSamples) |
| 38 | { |
| 39 | // To test if downsampling works as expected |
| 40 | #if SAVE_DOWNSAMPLED_AUDIO |
| 41 | auto file = juce::File::getSpecialLocation(juce::File::userDesktopDirectory).getChildFile("Test_Downsampled.wav"); |
| 42 | |
| 43 | std::unique_ptr<AudioFormatWriter> format_writer; |
| 44 | |
| 45 | format_writer.reset(WavAudioFormat().createWriterFor(new FileOutputStream(file), 22050, 1, 16, {}, 0)); |
| 46 | |
| 47 | if (format_writer != nullptr) { |
| 48 | AudioBuffer<float> tmp_buffer; |
| 49 | tmp_buffer.setSize(1, inNumSamples); |
| 50 | tmp_buffer.copyFrom(0, 0, inAudio, inNumSamples); |
| 51 | format_writer->writeFromAudioSampleBuffer(tmp_buffer, 0, inNumSamples); |
| 52 | |
| 53 | format_writer->flush(); |
| 54 | |
| 55 | file.revealToUser(); |
| 56 | } |
| 57 | #endif |
| 58 | |
| 59 | const float* stacked_cqt = mFeaturesCalculator.computeFeatures(inAudio, inNumSamples, mNumFrames); |
| 60 | |
| 61 | mOnsetsPG.resize(mNumFrames, std::vector<float>(static_cast<size_t>(NUM_FREQ_OUT), 0.0f)); |
| 62 | mNotesPG.resize(mNumFrames, std::vector<float>(static_cast<size_t>(NUM_FREQ_OUT), 0.0f)); |
| 63 | mContoursPG.resize(mNumFrames, std::vector<float>(static_cast<size_t>(NUM_FREQ_IN), 0.0f)); |
| 64 | |
| 65 | mOnsetsPG.shrink_to_fit(); |
| 66 | mNotesPG.shrink_to_fit(); |
| 67 | mContoursPG.shrink_to_fit(); |
| 68 | |
| 69 | mBasicPitchCNN.reset(); |
| 70 | |
| 71 | const size_t num_lh_frames = BasicPitchCNN::getNumFramesLookahead(); |
| 72 | |
| 73 | std::vector<float> zero_stacked_cqt(NUM_HARMONICS * NUM_FREQ_IN, 0.0f); |
| 74 | |
| 75 | // Run the CNN with 0 input and discard output (only for num_lh_frames) |
| 76 | for (int i = 0; i < num_lh_frames; i++) { |
| 77 | mBasicPitchCNN.frameInference(zero_stacked_cqt.data(), mContoursPG[0], mNotesPG[0], mOnsetsPG[0]); |
| 78 | } |
| 79 | |
| 80 | // Run the CNN with real inputs and discard outputs (only for num_lh_frames) |
| 81 | for (size_t frame_idx = 0; frame_idx < num_lh_frames; frame_idx++) { |
| 82 | mBasicPitchCNN.frameInference( |
| 83 | stacked_cqt + frame_idx * NUM_HARMONICS * NUM_FREQ_IN, mContoursPG[0], mNotesPG[0], mOnsetsPG[0]); |
| 84 | } |
| 85 | |
| 86 | // Run the CNN with real inputs and correct outputs |
| 87 | for (size_t frame_idx = num_lh_frames; frame_idx < mNumFrames; frame_idx++) { |
| 88 | mBasicPitchCNN.frameInference(stacked_cqt + frame_idx * NUM_HARMONICS * NUM_FREQ_IN, |
| 89 | mContoursPG[frame_idx - num_lh_frames], |
| 90 | mNotesPG[frame_idx - num_lh_frames], |
| 91 | mOnsetsPG[frame_idx - num_lh_frames]); |
| 92 | } |
| 93 | |
| 94 | // Run end with zeroes as input and last frames as output |
no test coverage detected