blob: 920d7a5233a47522b4c891f09ac606571ead9455 [file] [log] [blame]
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +01001//
George Gekov23c26272021-08-16 11:32:10 +01002// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +01003// SPDX-License-Identifier: MIT
4//
5
6#include "AudioCapture.hpp"
7#include <alsa/asoundlib.h>
8#include <sndfile.h>
9#include <samplerate.h>
10
George Gekov23c26272021-08-16 11:32:10 +010011namespace audio
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010012{
13 std::vector<float> AudioCapture::LoadAudioFile(std::string filePath)
14 {
15 SF_INFO inputSoundFileInfo;
George Gekov23c26272021-08-16 11:32:10 +010016 SNDFILE* infile = nullptr;
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010017 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;
George Gekov23c26272021-08-16 11:32:10 +010024 int outputFrames = ceilf(inputSoundFileInfo.frames * srcRatio);
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010025
26 // Convert to mono
George Gekov23c26272021-08-16 11:32:10 +010027 std::vector<float> monoData(inputSoundFileInfo.frames);
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010028 for(int i = 0; i < inputSoundFileInfo.frames; i++)
29 {
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010030 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;
George Gekov23c26272021-08-16 11:32:10 +010037 srcData.data_in = monoData.data();
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010038 srcData.input_frames = inputSoundFileInfo.frames;
George Gekov23c26272021-08-16 11:32:10 +010039
40 std::vector<float> dataOut(outputFrames);
41 srcData.data_out = dataOut.data();
42
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010043 srcData.output_frames = outputFrames;
44 srcData.src_ratio = srcRatio;
45
46 src_simple(&srcData, SRC_SINC_BEST_QUALITY, 1);
47
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010048 sf_close(infile);
49
George Gekov23c26272021-08-16 11:32:10 +010050 return dataOut;
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010051 }
52
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
58 bool AudioCapture::HasNext()
59 {
60 return m_window.HasNext();
61 }
62
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 {
George Gekov23c26272021-08-16 11:32:10 +010074 std::vector<float> audioData(windowSize, 0.0f);
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010075 for(int i = 0; i < remainingData; ++i)
76 {
George Gekov23c26272021-08-16 11:32:10 +010077 audioData[i] = *windowData;
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010078 if(i < remainingData - 1)
79 {
80 ++windowData;
81 }
82 }
George Gekov23c26272021-08-16 11:32:10 +010083 return audioData;
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010084 }
85 else
86 {
George Gekov23c26272021-08-16 11:32:10 +010087 std::vector<float> audioData(windowData, windowData + windowSize);
88 return audioData;
Éanna Ó Catháinc6ab02a2021-04-07 14:35:25 +010089 }
90 }
91 else
92 {
93 throw std::out_of_range("Error, end of audio data reached.");
94 }
95 }
George Gekov23c26272021-08-16 11:32:10 +010096} //namespace asr