update code.

This commit is contained in:
luocai 2024-09-04 20:17:15 +08:00
parent e8a3532cee
commit 4f3dc015f7
6 changed files with 116 additions and 13 deletions

View File

@ -12,31 +12,47 @@ void PlayerTask::setPath(const std::string &path) {
}
}
void PlayerTask::setChannels(int channels) {
if (m_channels != channels) {
m_channels = channels;
}
}
/*
ffmpeg将一个1通道mp3文件 2,16bit,16000pcm文件,
ffmpeg -i 20200316_1900.mp3 -ac 2 -ar 16000 -filter_complex "[0:a]pan=stereo|c0=0*c0|c1=1*c0[a]" -map "[a]" -f s16le -acodec pcm_s16le 20200316_1900.pcm
ffmpeg -i 20200316_1900.mp3 -ac 2 -ar 16000 -filter_complex "[0:a]pan=stereo|c0=0*c0|c1=1*c0[a]" -map "[a]" -f s16le -acodec pcm_s16le
20200316_1900.pcm
ffmpeg将一个1通道mp3文件 2,16bit,16000pcm文件,
ffmpeg -i 20200316_1900.mp3 -ac 2 -ar 16000 -filter_complex "[0:a]pan=stereo|c0=1*c0|c1=0*c0[a]" -map "[a]" -f s16le -acodec pcm_s16le 20200316_1900.pcm
ffmpeg -i 20200316_1900.mp3 -ac 2 -ar 16000 -filter_complex "[0:a]pan=stereo|c0=1*c0|c1=0*c0[a]" -map "[a]" -f s16le -acodec pcm_s16le
20200316_1900.pcm
ffmpeg -i 20200316_1900.mp3 -ac 2 -ar 16000 -f s16le -acodec pcm_s16le 20200316_1900_2ch.pcm
ffmpeg -i 20200316_1900.mp3 -ac 1 -ar 16000 -f s16le -acodec pcm_s16le 20200316_1900_1ch.pcm
20200316_1900.mp3
./Record --play --channels=1 --path=/sdcard/data/20200316_1900_1ch.pcm
./Record --play --path=/sdcard/data/20200316_1900_2ch.pcm
./Record --play --path=/sdcard/data/20200316_1900_left_silence.pcm
./Record --play --path=/sdcard/data/20200316_1900_right_silense.pcm
20240904160913.pcm
*/
// ./Record --play --path=/sdcard/data/20240904160913.pcm
void PlayerTask::run() {
using namespace Amass;
RkAudio::Format format;
format.channels = 2;
format.channels = m_channels;
format.period = 64;
m_output = std::make_shared<RkAudio::Output>();
if (!m_output->open(sizeof(uint16_t), format.sampleRate, format.channels, format.period, false)) {
LOG(error) << "audio output open failed.";
return;
}
m_buffer.resize(m_channels*sizeof(int16_t)*16* format.period);
play();
}
@ -47,10 +63,9 @@ void PlayerTask::play() {
LOG(info) << "play finished";
return;
}
char buffer[2 * sizeof(int16_t) * 16 * 64];
m_ifs->read(buffer, sizeof(buffer));
m_ifs->read(m_buffer.data(), m_buffer.size());
auto readedSize = m_ifs->gcount();
m_output->write(reinterpret_cast<const uint8_t *>(buffer), readedSize);
m_output->write(reinterpret_cast<const uint8_t *>(m_buffer.data()), readedSize);
boost::asio::post(*ioConext->ioContext(), [this]() { play(); });
}

View File

@ -151,7 +151,11 @@ bool Output::open(uint32_t sampleSize, uint32_t sampleRate, uint32_t channels, u
parameter.u32Channels = channels;
RK_MPI_AO_SetChnAttr(m_channel, &parameter);
RK_MPI_AO_EnableChn(m_channel);
auto status = RK_MPI_AO_EnableChn(m_channel);
if (status != 0) {
LOG(error) << "RK_MPI_AO_EnableChn() failed, status: " << status;
return false;
}
if (enableVqe) {
AO_VQE_CONFIG_S config = {0};

View File

@ -2,9 +2,53 @@
#include <speex/speex_echo.h>
#include <speex/speex_preprocess.h>
SpeexDsp::~SpeexDsp() {
close();
}
void SpeexDsp::start(int sampleRate, int channels, int period) {
close();
int frameSize = sampleRate * period / 1000; // 10-20 ms
int filterLength = sampleRate * 500 / 1000; // 100-500 ms
m_echoState = speex_echo_state_init_mc(frameSize, filterLength, channels, channels);
speex_echo_ctl(m_echoState, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
m_preprocessState = speex_preprocess_state_init(frameSize, sampleRate);
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_ECHO_STATE, m_echoState);
int32_t noiseSuppress = -25, i = 1;
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DENOISE, &i);
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress);
i = 0;
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_AGC, &i);
i = sampleRate;
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
i = 0;
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DEREVERB, &i);
float f = .0;
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
f = .0;
speex_preprocess_ctl(m_preprocessState, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
}
void SpeexDsp::close() {
if (m_preprocessState != nullptr) {
speex_preprocess_state_destroy(m_preprocessState);
m_preprocessState = nullptr;
}
if (m_echoState != nullptr) {
speex_echo_state_destroy(m_echoState);
m_echoState = nullptr;
}
}
void SpeexDsp::reset() {
if (m_state != nullptr) {
speex_echo_state_reset(m_state);
if (m_echoState != nullptr) {
speex_echo_state_reset(m_echoState);
}
}
@ -13,3 +57,21 @@ void SpeexDsp::preprocess(int16_t *pcm) {
speex_preprocess_run(m_preprocessState, pcm);
}
}
void SpeexDsp::echoPlayback(const int16_t *play) {
if (m_echoState != nullptr) {
speex_echo_playback(m_echoState, play);
}
}
void SpeexDsp::echoCapture(const int16_t *record, int16_t *out) {
if (m_echoState != nullptr) {
speex_echo_capture(m_echoState, record, out);
}
}
void SpeexDsp::echoCancellation(const int16_t *record, const int16_t *play, int16_t *out) {
if (m_echoState != nullptr) {
speex_echo_cancellation(m_echoState, record, play, out);
}
}

View File

@ -8,12 +8,20 @@ typedef struct SpeexPreprocessState_ SpeexPreprocessState;
class SpeexDsp {
public:
void preprocess(int16_t *pcm);
~SpeexDsp();
void start(int sampleRate, int channels, int period);
void close();
void preprocess(int16_t *pcm);
void echoCancellation(const int16_t *record, const int16_t *play, int16_t *out);
void echoPlayback(const int16_t *play);
void echoCapture(const int16_t *record, int16_t *out);
void reset();
private:
SpeexEchoState *m_state = nullptr;
SpeexPreprocessState *m_preprocessState=nullptr;
SpeexEchoState *m_echoState = nullptr;
SpeexPreprocessState *m_preprocessState = nullptr;
};
#endif // __SPEEXDSP_H__

View File

@ -78,7 +78,14 @@ int main(int argc, char **argv) {
if (variablesMap.count("path")) {
path = variablesMap["path"].as<std::string>();
}
int channels = 2;
if (variablesMap.count("channels")) {
channels = variablesMap["channels"].as<int>();
}
auto t = std::make_shared<PlayerTask>();
t->setChannels(channels);
t->setPath(path);
task = std::dynamic_pointer_cast<Task>(t);
}

View File

@ -5,6 +5,8 @@
#include <fstream>
#include <memory>
class SpeexDsp;
class Task {
public:
virtual void run() = 0;
@ -21,6 +23,7 @@ private:
class PlayerTask : public Task {
public:
void setChannels(int channels);
void setPath(const std::string &path);
void run() final;
@ -28,7 +31,9 @@ protected:
void play();
private:
int m_channels = 2;
std::string m_path;
std::vector<char> m_buffer;
std::shared_ptr<std::ifstream> m_ifs;
std::shared_ptr<RkAudio::Output> m_output;
};
@ -44,6 +49,8 @@ private:
bool m_vqeEnabled = false;
std::shared_ptr<RkAudio::Output> m_output;
std::shared_ptr<RkAudio::Input> m_input;
std::shared_ptr<SpeexDsp> m_speex;
std::vector<uint8_t> m_buffer;
};
#endif // __MAIN_H__