xref: /aosp_15_r20/external/armnn/samples/common/src/Audio/AudioCapture.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
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