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 -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 -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(); });
|
||||
}
|
@ -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, ¶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) {
|
||||
AO_VQE_CONFIG_S config = {0};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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__
|
@ -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);
|
||||
}
|
||||
|
@ -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__
|
Loading…
Reference in New Issue
Block a user