单击ALSA音调生成器

时间:2016-01-15 21:32:59

标签: c++ linux signal-processing alsa tone-generator

我正在学习在Raspberry Pi 2上使用ALSA。我用C ++编写了一个小型测试程序来生成440 Hz的测试音。它会产生音调,但音调中每秒钟会发出两次咔哒声。

有谁知道为什么会这样?代码如下。

#include <cmath>
#include <climits>
#include <iostream>
#include <alsa/asoundlib.h>

#include "definitions.hpp"

using namespace std;

int main() {
    int ret;

    snd_pcm_t* pcm_handle;  // device handle
    snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
    snd_pcm_hw_params_t* hwparams;  // hardware information
    char* pcm_name = strdup("plughw:0,0");  // on-board audio jack
    int rate = 48000;

    const uint16 freq = 440;
    long unsigned int bufferSize = 8192*4;
    const uint32 len = bufferSize*100;
    const float32 arg = 2 * 3.141592 * freq / rate;
    sint16 vals[len];

    for(int i = 0; i < len; i = i + 2) {
        vals[i] = SHRT_MAX * cos(arg * i / 2);
    }

    snd_pcm_hw_params_alloca(&hwparams);

    ret = snd_pcm_open(&pcm_handle, pcm_name, stream, 0);
    cout << "Opening: " << snd_strerror(ret) << endl;

    ret = snd_pcm_hw_params_any(pcm_handle, hwparams);
    cout << "Initializing hwparams structure: " << snd_strerror(ret) << endl;   

    ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams,
            SND_PCM_ACCESS_RW_INTERLEAVED);
    cout << "Setting access: " << snd_strerror(ret) << endl;

    ret = snd_pcm_hw_params_set_format(pcm_handle, hwparams,
            SND_PCM_FORMAT_S16_LE);
    cout << "Setting format: " << snd_strerror(ret) << endl;

    ret = snd_pcm_hw_params_set_rate(pcm_handle, hwparams,
            rate, (int)0);
    cout << "Setting rate: " << snd_strerror(ret) << endl;

    ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2); 
    cout << "Setting channels: " << snd_strerror(ret) << endl;

    ret = snd_pcm_hw_params_set_periods(pcm_handle, hwparams, 2, 0);
    cout << "Setting periods: " << snd_strerror(ret) << endl;

    ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams,
            &bufferSize);
    cout << "Setting buffer size: " << snd_strerror(ret) << endl;

    ret = snd_pcm_hw_params(pcm_handle, hwparams);
    cout << "Applying parameters: " << snd_strerror(ret) << endl;

    cout << endl << endl;


    const void* ptr = (const void*)&vals;
    int err;

    do {
        ptr += bufferSize;
        ret = snd_pcm_writei(pcm_handle,
                ptr, len);

        if(ret < 0) {
            err = snd_pcm_prepare(pcm_handle);
            cout << "Preparing: " << snd_strerror(err)
                << endl;
        }
    } while(ret < 0);

    cout << "Writing data: " << ret << ", " << snd_strerror(ret)
        << endl;
}

当你运行它时,你得到这个终端输出。当然,没有写入错误,只有写入的位数。

pi@raspberrypi:~/radio $ ./bin/alsatest 
Opening: Success
Initializing hwparams structure: Success
Setting access: Success
Setting format: Success
Setting rate: Success
Setting channels: Success
Setting periods: Success
Setting buffer size: Success
Applying parameters: Success


Writing data: 344110, Unknown error 344110

更新 - 下一天 好。我已将输出连接到我的便携式示波器,并看到以下波形。每次点击时,信号似乎都会出现不连续性。我添加了几行来计算我的正弦曲线阵列中有多少接近零的值,并且没有。奇怪的是,ALSA样本计划/test/pcm.c是一个完美的浪潮。也许我需要写一些非常小的块?我的代码与示例之间似乎没有太大区别。

enter image description here

0 个答案:

没有答案