【问题标题】:RtAudio - Playing samples from wav fileRtAudio - 从 wav 文件中播放样本
【发布时间】:2017-01-31 04:41:20
【问题描述】:

我目前正在尝试学习音频编程。我的目标是打开一个 wav 文件,提取所有内容并使用 RtAudio 播放样本。

我创建了一个 WaveLoader 类,让我可以提取样本和元数据。我使用this 指南来执行此操作,并使用 010 编辑器检查了一切是否正确。这是显示结构和数据的 010 编辑器的快照。

这就是我在 WaveLoader 类中存储原始样本的方式:

        data = new short[wave_data.payloadSize]; // - Allocates memory size of chunk size

        if (!fread(data, 1, wave_data.payloadSize, sound_file))
        {
            throw ("Could not read wav data");
        }

如果我打印出我得到的每个样本:1、-3、4、-5 ... 这似乎没问题。

问题是我不确定如何玩它们。这就是我所做的:

/*
 * Using PortAudio to play samples
 */
bool Player::Play() 
{
    ShowDevices();
    rt.showWarnings(true);

    RtAudio::StreamParameters oParameters; //, iParameters;
    oParameters.deviceId = rt.getDefaultOutputDevice();
    oParameters.firstChannel = 0;
    oParameters.nChannels = mAudio.channels;

    //iParameters.deviceId = rt.getDefaultInputDevice();
    //iParameters.nChannels = 2;

    unsigned int sampleRate = mAudio.sampleRate;

    // Use a buffer of 512, we need to feed callback with 512 bytes everytime!
    unsigned int nBufferFrames = 512;

    RtAudio::StreamOptions options;
    options.flags = RTAUDIO_SCHEDULE_REALTIME;
    options.flags = RTAUDIO_NONINTERLEAVED;

    //&parameters, NULL, RTAUDIO_FLOAT64,sampleRate, &bufferFrames, &mCallback, (void *)&rawData

    try {
        rt.openStream(&oParameters, NULL, RTAUDIO_SINT16, sampleRate, &nBufferFrames, &mCallback, (void*) &mAudio);
        rt.startStream();
    }
    catch (RtAudioError& e) {
        std::cout << e.getMessage() << std::endl;
        return false;
    }
    return true;
}

/*
* RtAudio Callback
*
*/
int mCallback(void * outputBuffer, void * inputBuffer, unsigned int nBufferFrames, double streamTime, RtAudioStreamStatus status, void * userData)
{
    unsigned int i = 0;
    short *out = static_cast<short*>(outputBuffer);
    auto *data = static_cast<Player::AUDIO_DATA*>(userData);

    // if i is more than our data size, we are done!
    if (i > data->dataSize) return 1;

    // First time callback is called data->ptr is 0, this means that the offset is 0
    // Second time data->ptr is 1, this means offset = nBufferFrames (512) * 1 = 512
    unsigned int offset = nBufferFrames * data->ptr++;

    printf("Offset: %i\n", offset);
    // First time callback is called offset is 0, we are starting from 0 and looping nBufferFrames (512) times, this gives us 512 bytes
    // Second time, the offset is 1, we are starting from 512 bytes and looping to 512 + 512 = 1024 
    for (i = offset; i < offset + nBufferFrames; ++i)
    {
        short sample = data->rawData[i]; // Get raw sample from our struct
        *out++ = sample;                // Pass to output buffer for playback

        printf("Current sample value: %i\n", sample);       // this is showing 1, -3, 4, -5 check 010 editor
    }

    printf("Current time: %f\n", streamTime);
    return 0;
}

在回调函数内部,当我打印出样本值时,我得到的结果与 010 编辑器完全一样?为什么 rtaudio 不播放它们。这里有什么问题?我需要将样本值标准化到 -1 到 1 之间吗?

编辑: 我正在尝试播放的 wav 文件:

  • 块大小:16
  • 格式:1
  • 频道:1
  • 采样率:48000
  • 字节速率:96000
  • 块对齐:2
  • BitPerSample:16
  • 原始样本总大小:2217044 字节

【问题讨论】:

    标签: c++ audio wav wave rtaudio


    【解决方案1】:

    由于某种原因,当我将输入参数传递给 openStream() 时它可以工作

        RtAudio::StreamParameters oParameters, iParameters;
        oParameters.deviceId = rt.getDefaultOutputDevice();
        oParameters.firstChannel = 0;
        //oParameters.nChannels = mAudio.channels;
        oParameters.nChannels = mAudio.channels;
    
        iParameters.deviceId = rt.getDefaultInputDevice();
        iParameters.nChannels = 1;
    
        unsigned int sampleRate = mAudio.sampleRate;
    
        // Use a buffer of 512, we need to feed callback with 512 bytes everytime!
        unsigned int nBufferFrames = 512;
    
        RtAudio::StreamOptions options;
        options.flags = RTAUDIO_SCHEDULE_REALTIME;
        options.flags = RTAUDIO_NONINTERLEAVED;
    
        //&parameters, NULL, RTAUDIO_FLOAT64,sampleRate, &bufferFrames, &mCallback, (void *)&rawData
    
        try {
            rt.openStream(&oParameters, &iParameters, RTAUDIO_SINT16, sampleRate, &nBufferFrames, &mCallback, (void*) &mAudio);
            rt.startStream();
        }
        catch (RtAudioError& e) {
            std::cout << e.getMessage() << std::endl;
            return false;
        }
        return true;
    

    当我尝试播放我的麦克风时,它是如此随机。我留下了输入参数,我的 wav 文件突然播放了。这是一个错误吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 2022-06-21
      • 1970-01-01
      • 2010-11-19
      相关资源
      最近更新 更多