如何将基本音频信号检测为更大的信号(mpg123 输出信号)
How to detect a basic audio signal into a much bigger one (mpg123 output signal)
我是信号处理的新手,我不太了解基础知识(以及更多知识)。到目前为止,对于我理解中的任何错误,我深表歉意。
我正在编写 C 代码来检测一个基本信号(18Hz 简单正弦波持续 2 秒,使用 Audacity 生成它非常简单)到一个更大的 mp3 文件中。我读取 mp3 文件并复制它,直到我匹配声音信号。
要匹配的信号是{第一个通道:18Hz sin。信号,第二通道:nothing/doesn无关紧要)。
为了匹配声音,我正在计算 mp3 的频率,直到找到 18Hz 频率的合适百分比。在 ~ 2 秒期间。由于这个频率不是很常见,所以我不必非常精确地匹配它。
我使用 mpg123 转换我的文件,我用它填充缓冲区 returns。我初始化它以将 mp3 转换为 Mono RAW 音频:
初始化:
int ret;
const long *rates;
size_t rate_count, i;
mpg123_rates(&rates, &rate_count);
mpg123_handle *m = mpg123_new(NULL, &ret);
mpg123_format_none(m);
for(i=0; i<rate_count; ++i)
mpg123_format(m, rates[i], MPG123_MONO, MPG123_ENC_SIGNED_32);
if(m == NULL)
{
//err
} else {
mpg123_open_feed(m);
}
</code>(...)</p>
<pre><code>unsigned char out[8*MAX_MP3_BUF_SIZE];
ret = mpg123_decode(m, buf->data, buf->size, out, 8*MAX_MP3_BUF_SIZE, &size);
`(...)
unsigned char out[8*MAX_MP3_BUF_SIZE];
ret = mpg123_decode(m, buf->data, buf->size, out, 8*MAX_MP3_BUF_SIZE, &size);
(...)`
但我必须考虑如何获得结果缓冲区来计算 FFT 以获得频率。
//FREQ Calculation with libfftw3
int transform_size = MAX_MP3_BUF_SIZE * 2;
fftw_complex *fftout = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * transform_size);
fftw_complex *fftin = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * transform_size);
fftw_plan p = fftw_plan_dft_r2c_1d(transform_size, fftin, fftout, FFTW_ESTIMATE);
我可以将一个好的 RAW 音频(PCM?)放入缓冲区(如果我写入它,它可以被读取并用 sox 转换成 wave:
sox --magic -r 44100 -e signed -b 32 -c 1 rps.raw rps.wav
感谢任何帮助。我对信号处理的了解很差,我什至不确定如何使用 FFT 来获取信号的频率。代码仅供参考,它包含在一个更大的项目中(一个简单的 grep 不是一个选项)
不要为此使用 MP3。您的 18 Hz 很可能会消失或至少会失真。 18 Hz 将低于可听见的频率。 MP3 和其他有损算法使用各种技术来消除我们不会听到的声音。
假设PCM,因为你只需要一个频段,可以考虑使用Goertzel algorithm。对于您的用例,这比 FFT/DFT 更有效。
我是信号处理的新手,我不太了解基础知识(以及更多知识)。到目前为止,对于我理解中的任何错误,我深表歉意。
我正在编写 C 代码来检测一个基本信号(18Hz 简单正弦波持续 2 秒,使用 Audacity 生成它非常简单)到一个更大的 mp3 文件中。我读取 mp3 文件并复制它,直到我匹配声音信号。
要匹配的信号是{第一个通道:18Hz sin。信号,第二通道:nothing/doesn无关紧要)。 为了匹配声音,我正在计算 mp3 的频率,直到找到 18Hz 频率的合适百分比。在 ~ 2 秒期间。由于这个频率不是很常见,所以我不必非常精确地匹配它。
我使用 mpg123 转换我的文件,我用它填充缓冲区 returns。我初始化它以将 mp3 转换为 Mono RAW 音频: 初始化:
int ret;
const long *rates;
size_t rate_count, i;
mpg123_rates(&rates, &rate_count);
mpg123_handle *m = mpg123_new(NULL, &ret);
mpg123_format_none(m);
for(i=0; i<rate_count; ++i)
mpg123_format(m, rates[i], MPG123_MONO, MPG123_ENC_SIGNED_32);
if(m == NULL)
{
//err
} else {
mpg123_open_feed(m);
}
</code>(...)</p>
<pre><code>unsigned char out[8*MAX_MP3_BUF_SIZE];
ret = mpg123_decode(m, buf->data, buf->size, out, 8*MAX_MP3_BUF_SIZE, &size);
`(...)
unsigned char out[8*MAX_MP3_BUF_SIZE];
ret = mpg123_decode(m, buf->data, buf->size, out, 8*MAX_MP3_BUF_SIZE, &size);
(...)`
但我必须考虑如何获得结果缓冲区来计算 FFT 以获得频率。
//FREQ Calculation with libfftw3
int transform_size = MAX_MP3_BUF_SIZE * 2;
fftw_complex *fftout = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * transform_size);
fftw_complex *fftin = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * transform_size);
fftw_plan p = fftw_plan_dft_r2c_1d(transform_size, fftin, fftout, FFTW_ESTIMATE);
我可以将一个好的 RAW 音频(PCM?)放入缓冲区(如果我写入它,它可以被读取并用 sox 转换成 wave: sox --magic -r 44100 -e signed -b 32 -c 1 rps.raw rps.wav
感谢任何帮助。我对信号处理的了解很差,我什至不确定如何使用 FFT 来获取信号的频率。代码仅供参考,它包含在一个更大的项目中(一个简单的 grep 不是一个选项)
不要为此使用 MP3。您的 18 Hz 很可能会消失或至少会失真。 18 Hz 将低于可听见的频率。 MP3 和其他有损算法使用各种技术来消除我们不会听到的声音。
假设PCM,因为你只需要一个频段,可以考虑使用Goertzel algorithm。对于您的用例,这比 FFT/DFT 更有效。