1 // 2 // Copyright © 2021 Arm Ltd and Contributors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 // 5 6 #include "AudioCapture.hpp" 7 #include <alsa/asoundlib.h> 8 #include <sndfile.h> 9 #include <samplerate.h> 10 11 namespace audio 12 { LoadAudioFile(std::string filePath)13 std::vector<float> AudioCapture::LoadAudioFile(std::string filePath) 14 { 15 SF_INFO inputSoundFileInfo; 16 SNDFILE* infile = nullptr; 17 infile = sf_open(filePath.c_str(), SFM_READ, &inputSoundFileInfo); 18 19 float audioIn[inputSoundFileInfo.channels * inputSoundFileInfo.frames]; 20 sf_read_float(infile, audioIn, inputSoundFileInfo.channels * inputSoundFileInfo.frames); 21 22 float sampleRate = 16000.0f; 23 float srcRatio = sampleRate / (float)inputSoundFileInfo.samplerate; 24 int outputFrames = ceilf(inputSoundFileInfo.frames * srcRatio); 25 26 // Convert to mono 27 std::vector<float> monoData(inputSoundFileInfo.frames); 28 for(int i = 0; i < inputSoundFileInfo.frames; i++) 29 { 30 for(int j = 0; j < inputSoundFileInfo.channels; j++) 31 monoData[i] += audioIn[i * inputSoundFileInfo.channels + j]; 32 monoData[i] /= inputSoundFileInfo.channels; 33 } 34 35 // Resample 36 SRC_DATA srcData; 37 srcData.data_in = monoData.data(); 38 srcData.input_frames = inputSoundFileInfo.frames; 39 40 std::vector<float> dataOut(outputFrames); 41 srcData.data_out = dataOut.data(); 42 43 srcData.output_frames = outputFrames; 44 srcData.src_ratio = srcRatio; 45 46 src_simple(&srcData, SRC_SINC_BEST_QUALITY, 1); 47 48 sf_close(infile); 49 50 return dataOut; 51 } 52 InitSlidingWindow(float * data,size_t dataSize,int minSamples,size_t stride)53 void AudioCapture::InitSlidingWindow(float* data, size_t dataSize, int minSamples, size_t stride) 54 { 55 this->m_window = SlidingWindow<const float>(data, dataSize, minSamples, stride); 56 } 57 HasNext()58 bool AudioCapture::HasNext() 59 { 60 return m_window.HasNext(); 61 } 62 Next()63 std::vector<float> AudioCapture::Next() 64 { 65 if (this->m_window.HasNext()) 66 { 67 int remainingData = this->m_window.RemainingData(); 68 const float* windowData = this->m_window.Next(); 69 70 size_t windowSize = this->m_window.GetWindowSize(); 71 72 if(remainingData < windowSize) 73 { 74 std::vector<float> audioData(windowSize, 0.0f); 75 for(int i = 0; i < remainingData; ++i) 76 { 77 audioData[i] = *windowData; 78 if(i < remainingData - 1) 79 { 80 ++windowData; 81 } 82 } 83 return audioData; 84 } 85 else 86 { 87 std::vector<float> audioData(windowData, windowData + windowSize); 88 return audioData; 89 } 90 } 91 else 92 { 93 throw std::out_of_range("Error, end of audio data reached."); 94 } 95 } 96 } //namespace asr