update code.
This commit is contained in:
parent
e8a3532cee
commit
4f3dc015f7
@ -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,16000采样率的pcm文件,但是左通道数据为静音
|
ffmpeg将一个1通道mp3文件,转换为 2通道,16bit,16000采样率的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 -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,16000采样率的pcm文件,但是右通道数据为静音
|
ffmpeg将一个1通道mp3文件,转换为 2通道,16bit,16000采样率的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 -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
|
// ./Record --play --path=/sdcard/data/20240904160913.pcm
|
||||||
void PlayerTask::run() {
|
void PlayerTask::run() {
|
||||||
using namespace Amass;
|
using namespace Amass;
|
||||||
|
|
||||||
RkAudio::Format format;
|
RkAudio::Format format;
|
||||||
format.channels = 2;
|
format.channels = m_channels;
|
||||||
format.period = 64;
|
format.period = 64;
|
||||||
m_output = std::make_shared<RkAudio::Output>();
|
m_output = std::make_shared<RkAudio::Output>();
|
||||||
if (!m_output->open(sizeof(uint16_t), format.sampleRate, format.channels, format.period, false)) {
|
if (!m_output->open(sizeof(uint16_t), format.sampleRate, format.channels, format.period, false)) {
|
||||||
LOG(error) << "audio output open failed.";
|
LOG(error) << "audio output open failed.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
m_buffer.resize(m_channels*sizeof(int16_t)*16* format.period);
|
||||||
play();
|
play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,10 +63,9 @@ void PlayerTask::play() {
|
|||||||
LOG(info) << "play finished";
|
LOG(info) << "play finished";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char buffer[2 * sizeof(int16_t) * 16 * 64];
|
m_ifs->read(m_buffer.data(), m_buffer.size());
|
||||||
m_ifs->read(buffer, sizeof(buffer));
|
|
||||||
auto readedSize = m_ifs->gcount();
|
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(); });
|
boost::asio::post(*ioConext->ioContext(), [this]() { play(); });
|
||||||
}
|
}
|
@ -151,7 +151,11 @@ bool Output::open(uint32_t sampleSize, uint32_t sampleRate, uint32_t channels, u
|
|||||||
parameter.u32Channels = channels;
|
parameter.u32Channels = channels;
|
||||||
|
|
||||||
RK_MPI_AO_SetChnAttr(m_channel, ¶meter);
|
RK_MPI_AO_SetChnAttr(m_channel, ¶meter);
|
||||||
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) {
|
if (enableVqe) {
|
||||||
AO_VQE_CONFIG_S config = {0};
|
AO_VQE_CONFIG_S config = {0};
|
||||||
|
@ -2,9 +2,53 @@
|
|||||||
#include <speex/speex_echo.h>
|
#include <speex/speex_echo.h>
|
||||||
#include <speex/speex_preprocess.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() {
|
void SpeexDsp::reset() {
|
||||||
if (m_state != nullptr) {
|
if (m_echoState != nullptr) {
|
||||||
speex_echo_state_reset(m_state);
|
speex_echo_state_reset(m_echoState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,3 +57,21 @@ void SpeexDsp::preprocess(int16_t *pcm) {
|
|||||||
speex_preprocess_run(m_preprocessState, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,11 +8,19 @@ typedef struct SpeexPreprocessState_ SpeexPreprocessState;
|
|||||||
|
|
||||||
class SpeexDsp {
|
class SpeexDsp {
|
||||||
public:
|
public:
|
||||||
|
~SpeexDsp();
|
||||||
|
void start(int sampleRate, int channels, int period);
|
||||||
|
void close();
|
||||||
void preprocess(int16_t *pcm);
|
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();
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpeexEchoState *m_state = nullptr;
|
SpeexEchoState *m_echoState = nullptr;
|
||||||
SpeexPreprocessState *m_preprocessState = nullptr;
|
SpeexPreprocessState *m_preprocessState = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,7 +78,14 @@ int main(int argc, char **argv) {
|
|||||||
if (variablesMap.count("path")) {
|
if (variablesMap.count("path")) {
|
||||||
path = variablesMap["path"].as<std::string>();
|
path = variablesMap["path"].as<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int channels = 2;
|
||||||
|
if (variablesMap.count("channels")) {
|
||||||
|
channels = variablesMap["channels"].as<int>();
|
||||||
|
}
|
||||||
|
|
||||||
auto t = std::make_shared<PlayerTask>();
|
auto t = std::make_shared<PlayerTask>();
|
||||||
|
t->setChannels(channels);
|
||||||
t->setPath(path);
|
t->setPath(path);
|
||||||
task = std::dynamic_pointer_cast<Task>(t);
|
task = std::dynamic_pointer_cast<Task>(t);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class SpeexDsp;
|
||||||
|
|
||||||
class Task {
|
class Task {
|
||||||
public:
|
public:
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
@ -21,6 +23,7 @@ private:
|
|||||||
|
|
||||||
class PlayerTask : public Task {
|
class PlayerTask : public Task {
|
||||||
public:
|
public:
|
||||||
|
void setChannels(int channels);
|
||||||
void setPath(const std::string &path);
|
void setPath(const std::string &path);
|
||||||
void run() final;
|
void run() final;
|
||||||
|
|
||||||
@ -28,7 +31,9 @@ protected:
|
|||||||
void play();
|
void play();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int m_channels = 2;
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
|
std::vector<char> m_buffer;
|
||||||
std::shared_ptr<std::ifstream> m_ifs;
|
std::shared_ptr<std::ifstream> m_ifs;
|
||||||
std::shared_ptr<RkAudio::Output> m_output;
|
std::shared_ptr<RkAudio::Output> m_output;
|
||||||
};
|
};
|
||||||
@ -44,6 +49,8 @@ private:
|
|||||||
bool m_vqeEnabled = false;
|
bool m_vqeEnabled = false;
|
||||||
std::shared_ptr<RkAudio::Output> m_output;
|
std::shared_ptr<RkAudio::Output> m_output;
|
||||||
std::shared_ptr<RkAudio::Input> m_input;
|
std::shared_ptr<RkAudio::Input> m_input;
|
||||||
|
std::shared_ptr<SpeexDsp> m_speex;
|
||||||
|
std::vector<uint8_t> m_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __MAIN_H__
|
#endif // __MAIN_H__
|
Loading…
Reference in New Issue
Block a user