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