SDL音频间距 - 播放速率

时间:2017-02-24 15:08:01

标签: c++ audio sdl sdl-2

我的目标是将引擎的RPM连接到声音的音高。我使用SDL作为我的音频后端。

所以我的想法是从波形缓冲区中采样比正常情况更快。因此,通过跟踪和错误,我现在可以一步一步地发出我的引擎声音"

问题#1

如果我更改此部分:

audioBuff +=  1 + pitch * 2;

audioBuff += 2

我只是吵闹。为什么?这与立体声频道有关吗?

问题#2

如何将其设为线性音高?目前它是一个"踩踏"沥青。

以下是完整代码:

#include "SDL2/SDL.h"
#include <iostream>



void audioCallback(void* userdata, Uint8 *stream, int len);

Uint8 *audioBuff = nullptr;
Uint8 *audioBuffEnd = nullptr;
Uint32 audioLen = 0;
bool quit = false;
Uint16 pitch = 0;

int main()
{
    if(SDL_Init(SDL_INIT_AUDIO) < 0)
        return -1;

    Uint32 wavLen = 0;
    Uint8 *wavBuff = nullptr;
    SDL_AudioSpec wavSpec;

    if(SDL_LoadWAV("test.wav", &wavSpec, &wavBuff, &wavLen) == nullptr)
    {
        return 1;
    } 
    wavSpec.callback = audioCallback;
    wavSpec.userdata = nullptr;
    wavSpec.format = AUDIO_S16;
    wavSpec.samples = 2048;
    audioBuff = wavBuff;
    audioBuffEnd = &wavBuff[wavLen];
    audioLen = wavLen;

    if( SDL_OpenAudio(&wavSpec, NULL) < 0)
    {
        fprintf(stderr, "Could not open audio: %s\n", SDL_GetError());
        return 1;
    }

    SDL_PauseAudio(0);
    while(!quit)
    {
        SDL_Delay(500);
        pitch ++;

    }

    SDL_CloseAudio();
    SDL_FreeWAV(wavBuff);
    return 0;
}


Uint32 sampleIndex = 0;
void audioCallback(void* userdata, Uint8 *stream, int len)
{
    Uint32 length = (Uint32)len;
    length = (length > audioLen ? audioLen : length);

    for(Uint32 i = 0; i < length; i++)
    {
        if(audioBuff > audioBuffEnd)
        {
            quit = true;
            return;
        }
        // why pitch * 2?
        // how to get a smooth pitch?
        stream[i] = audioBuff[0];
        audioBuff +=  1 + pitch * 2;
        fprintf(stdout, "pitch: %u\n", pitch);
    }
}

1 个答案:

答案 0 :(得分:1)

您将音频格式设置为AUDIO_S16,这是&#34;签名的16位小端样本&#34;。每个样本都是两个字节,第一个字节是LSB。当您读取audioCallback中的数据时,您将其作为字节(8位)读取,然后将这些字节传递回预期为16位的字节。你因此而受到噪音的影响,当你使用audioBuff +=2;时,你总是会读取音频样本的LSB,这在使用时会产生噪音。

您应该始终使用16位或8位样本。