我正在尝试为声卡生成音调(频率:1950 Hz,持续时间:40 毫秒,电平:-30 db,右声道(立体声),在 steam 1 上)。最终,我想播放其中两个音调(一个转到通道 1,一个转到通道 2)。
任何帮助或指导将不胜感激。
谢谢DW
嗨,比约恩,我试过这个,但我没有得到我所期望的频率(加上似乎声音不干净)。任何想法出了什么问题?我非常感谢任何帮助。
#define SAMPLE_RATE (44100)
#define TABLE_SIZE (200)
float FREQUENCY = 422;
...
for(int i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( (double)i * ((2.0 * M_PI)/(double)SAMPLE_RATE) * FREQUENCY );
}
data.left_phase = 0;
data.right_phase = 0;
...
... in callback function ...
for(unsigned long i = 0; i < framesPerBuffer; i++ )
{
// fill output buffer with sin wave
*out++ = data->amp * data->sine[data->left_phase]; // left
*out++ = data->amp * data->sine[data->right_phase]; // right
data->left_phase += 1;
if( data->left_phase >= TABLE_SIZE )
data->left_phase -= TABLE_SIZE;
data->right_phase += 1;
if( data->right_phase >= TABLE_SIZE )
data->right_phase -= TABLE_SIZE;
}
PortAudio 有生成音调的示例代码,您只需要弄清楚频率即可。例如,请参阅此答案:
[端口音频]传输和检测频率 - 视窗
更新:
与其尝试存储正弦数据表,不如使用以下公式简单地计算回调中的正弦值:
振幅[n] = sin( n * 期望频率 * 2 * pi/采样率 )
所以(未经测试)你的代码将看起来像这样:
typedef struct
{
long n;
} MyData;
float FREQUENCY = 422;
static int MyCallback(
const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData
)
{
MyData *data = (MyData*)userData;
float *out = (float*)outputBuffer;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
for(unsigned long i = 0; i < framesPerBuffer; i++ )
{
// fill output buffer with sin wave
float v = sin( data->n * FREQUENCY * 2 * PI / (float) SAMPLERATE )
*out++ = v; // left
*out++ = v; // right
}
return paContinue;
}
这段代码并非没有问题:例如,最终 n 将"环绕",我不确定随着输入变大,sin 是否仍然准确和有效。尽管如此,这是一个很好的起点,如果您只需要在现代硬件上生成几秒钟的音调,那么这确实是您所需要的。如果您需要更花哨的东西,请先将其工作,然后您可以担心使用 LUT 使其更高效、更强大。