| 536 | } |
| 537 | |
| 538 | Utils::Result GranularSynth::loadAudioFile(juce::File file) { |
| 539 | juce::AudioFormatReader* formatReader = mFormatManager.createReaderFor(file); |
| 540 | if (formatReader == nullptr) return {false, "Opening failed: unsupported file format"}; |
| 541 | |
| 542 | juce::AudioBuffer<float> fileAudioBuffer; |
| 543 | const int length = static_cast<int>(formatReader->lengthInSamples); |
| 544 | fileAudioBuffer.setSize(1, length); |
| 545 | formatReader->read(&fileAudioBuffer, 0, length, 0, true, false); |
| 546 | |
| 547 | // .mp3 files, unlike .wav files, can contain PCM values greater than abs(1.0) (aka, clipping) which will produce awful |
| 548 | // sounding grains, so normalize the gain of any mp3 file clipping before using anywhere |
| 549 | if (file.getFileExtension() == ".mp3") { |
| 550 | float absMax = 0.0f; |
| 551 | for (int i = 0; i < fileAudioBuffer.getNumChannels(); i++) { |
| 552 | juce::Range<float> range = |
| 553 | juce::FloatVectorOperations::findMinAndMax(fileAudioBuffer.getReadPointer(i), fileAudioBuffer.getNumSamples()); |
| 554 | absMax = juce::jmax(absMax, std::abs(range.getStart()), std::abs(range.getEnd())); |
| 555 | } |
| 556 | if (absMax > 1.0) { |
| 557 | fileAudioBuffer.applyGain(1.0f / absMax); |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | Utils::resampleAudioBuffer(fileAudioBuffer, mInputBuffer, formatReader->sampleRate, mSampleRate); |
| 562 | |
| 563 | // should not need the file anymore as we want to work with the resampled input buffer across the rest of the plugin |
| 564 | delete (formatReader); |
| 565 | |
| 566 | return {true, ""}; |
| 567 | } |
| 568 | |
| 569 | Utils::Result GranularSynth::loadPreset(juce::File file) { |
| 570 | juce::FileInputStream input(file); |
no test coverage detected