2017-02-24 3 views
1

Mein Ziel ist es, die Drehzahl eines Motors mit der Tonhöhe eines Sounds zu verbinden. Ich verwende SDL als mein Audio-Backend.SDL Audio Pitch - Wiedergabegeschwindigkeit

Also war meine Idee, aus dem Wellenpuffer schneller als normal zu probieren. So kann ich meinen Motorsound durch "Trail and Error" Schritt für Schritt pitchen.

Frage # 1

Wenn ich diesen Teil ändern von:

audioBuff += 1 + pitch * 2; 

zu

audioBuff += 2 

bekomme ich nur Lärm. Warum? Hat das mit Stereokanälen zu tun?

Frage # 2

Wie kann ich das eine lineare Steigung machen? Derzeit ist es eine "Schritt" -Pitch.

Hier ist der vollständige Code:

#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

Was meinst du mit "linearer Abstand"? – 1201ProgramAlarm

+0

Ich stelle die gleiche Frage selbst @ 1201ProgramAlarm – Hydren

+0

Kann Tonhöhe auf einen Mix_Chunk von SDL_mixer angewendet werden? – Hydren

Antwort

1

Sie das Audioformat zu AUDIO_S16 Einstellung, die "16-Bit-Little-Endian-Proben" wird. Jeder Abtastwert besteht aus zwei Bytes, wobei das erste Byte das LSB ist. Wenn Sie die Daten in audioCallback lesen, lesen Sie es als Bytes (8 Bits) und dann diese Bytes zurück zu etwas, das 16 Bits erwartet. Sie bekommen deswegen Rauschen, und wenn Sie audioBuff +=2; verwenden, lesen Sie immer das LSB des Audio-Samples, das im Wesentlichen Rauschen ist, wenn es auf diese Weise verwendet wird.

Sie sollten konsequent entweder 16-Bit- oder 8-Bit-Samples verwenden.

+0

Ok danke. So sieht meine Callback-Funktion nun aus: 'void audioCallback (void * userdata, Uint8 * stream, int len) { Uint32 length = (Uint32) len; für (Uint32 i = 0; i audioBuffEnd) { quit = true; Rückkehr; } stream [i] = audioBuff [0]; i ++; stream [i] = audioBuff [1]; audioBuff + = 2 * Tonhöhe; } } ' – MadSystem