sdl-audio/example-test-code/audiotest.c

172 lines
5.2 KiB
C

#include <SDL2/SDL.h>
#include <SDL2/SDL_audio.h>
#include <stdio.h>
/*
* Audio INFO: audio related declarations and callback here.
*/
const int MAX_RECORDING_SECONDS = 2;
const int RECORDING_BUFFER_SECONDS = MAX_RECORDING_SECONDS + 1;
int num_devices = 0;
int num_recdevices = 0;
int num_playdevices = 0;
//Recording data buffer
Uint8* gRecordingBuffer = NULL;
//Size of data buffer
Uint32 gBufferByteSize = 0;
//Position in data buffer
Uint32 gBufferBytePosition = 0;
void audioRecordingCallback(void* userdata, Uint8* stream, int len )
{
memcpy(&gRecordingBuffer[ gBufferBytePosition ], stream, len);
gBufferBytePosition += len;
printf("Recording Callback: %u\n", *stream);
}
void audioPlaybackCallback(void* userdata, Uint8* stream, int len )
{
memcpy(stream, &gRecordingBuffer[ gBufferBytePosition ], len);
gBufferBytePosition += len;
printf("Playback Callback: %u\n", *stream);
}
int main(int argc, char* argv[])
{
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
printf("SDL init failed: %s\n", SDL_GetError());
return 1;
}
printf("SDL init success: %s\n", SDL_GetError());
while (1) {
int go = 0;
while (!go) {
printf("q to quit, Enter to continue\n");
char ch = getchar();
switch (ch) {
case 'q':
goto end;
break;
case '\n':
go = 1;
break;
}
}
SDL_AudioDeviceID recordingDeviceId = 0;
SDL_AudioDeviceID playbackDeviceId = 0;
SDL_AudioSpec gReceivedRecordingSpec;
SDL_AudioSpec gReceivedPlaybackSpec;
SDL_AudioSpec desiredRecordingSpec;
SDL_zero(desiredRecordingSpec);
desiredRecordingSpec.freq = 44100;
desiredRecordingSpec.format = AUDIO_S16;
desiredRecordingSpec.channels = 2;
desiredRecordingSpec.samples = 4096;
desiredRecordingSpec.callback = audioRecordingCallback;
SDL_AudioSpec desiredPlaybackSpec;
SDL_zero(desiredPlaybackSpec);
desiredPlaybackSpec.freq = 44100;
desiredPlaybackSpec.format = AUDIO_S16; // AUDIO_F32;
desiredPlaybackSpec.channels = 2;
desiredPlaybackSpec.samples = 4096;
desiredPlaybackSpec.callback = audioPlaybackCallback;
//Maximum position in data buffer for recording
Uint32 gBufferByteMaxPosition = 0;
printf("Audio Driver: %s\n", SDL_GetCurrentAudioDriver());
num_recdevices = SDL_GetNumAudioDevices(1);
if(num_recdevices < 1) {
printf( "Unable to get audio capture device! SDL Error: %s\n", SDL_GetError() );
return 0;
}
printf("Num audio recording devices: %i\n", num_recdevices);
for(int i = 0; i < num_recdevices; ++i) {
const char* deviceName = SDL_GetAudioDeviceName(i, 1);
printf("REC: %d - %s\n", i, deviceName);
}
num_playdevices = SDL_GetNumAudioDevices(0);
if(num_playdevices < 1) {
printf( "Unable to get audio playback device! SDL Error: %s\n", SDL_GetError() );
return 0;
}
printf("Num audio playback devices: %i\n", num_playdevices);
for(int i = 0; i < num_recdevices; ++i) {
const char* deviceName = SDL_GetAudioDeviceName(i, 0);
printf("PBK: %d - %s\n", i, deviceName);
}
const char* device_name = SDL_GetAudioDeviceName(2, 1);
recordingDeviceId = SDL_OpenAudioDevice(device_name, SDL_TRUE, &desiredRecordingSpec, &gReceivedRecordingSpec, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
if(recordingDeviceId == 0) {
printf("Failed to open recording device! SDL Error: %s", SDL_GetError() );
return 1;
}
int bytesPerSample = gReceivedRecordingSpec.channels * (SDL_AUDIO_BITSIZE(gReceivedRecordingSpec.format) / 8);
int bytesPerSecond = gReceivedRecordingSpec.freq * bytesPerSample;
gBufferByteSize = RECORDING_BUFFER_SECONDS * bytesPerSecond;
gBufferByteMaxPosition = MAX_RECORDING_SECONDS * bytesPerSecond;
printf("bytesPerSample %d, bytesPerSecond %d\n", bytesPerSample,bytesPerSecond);
printf("gBufferByteSize %d, gBufferByteMaxPosition %d\n", gBufferByteSize,gBufferByteMaxPosition);
playbackDeviceId = SDL_OpenAudioDevice( NULL, 0, &desiredPlaybackSpec, &gReceivedPlaybackSpec, SDL_AUDIO_ALLOW_FORMAT_CHANGE );
if(playbackDeviceId == 0) {
printf("Failed to open playback device! SDL Error: %s", SDL_GetError());
return 1;
}
gRecordingBuffer = malloc(gBufferByteSize);
memset(gRecordingBuffer, 0, gBufferByteSize);
gBufferBytePosition = 0;
SDL_Delay(100);
SDL_PauseAudioDevice( recordingDeviceId, SDL_FALSE );
while(1) {
SDL_LockAudioDevice( recordingDeviceId );
if(gBufferBytePosition > gBufferByteMaxPosition) {
printf("end\n");
SDL_UnlockAudioDevice( recordingDeviceId );
SDL_PauseAudioDevice( recordingDeviceId, SDL_TRUE );
break;
//} else {
// printf("bufferPos %d\n",gBufferBytePosition);
}
SDL_UnlockAudioDevice( recordingDeviceId );
}
printf("playback\n");
gBufferBytePosition = 0;
SDL_PauseAudioDevice(playbackDeviceId, 0);
while(1) {
SDL_LockAudioDevice(playbackDeviceId);
if(gBufferBytePosition > gBufferByteMaxPosition) {
printf("end\n");
SDL_UnlockAudioDevice(playbackDeviceId);
SDL_PauseAudioDevice(playbackDeviceId, SDL_TRUE);
break;
}
SDL_UnlockAudioDevice(playbackDeviceId);
}
printf("Cleanup\n");
free(gRecordingBuffer);
SDL_CloseAudioDevice(recordingDeviceId);
SDL_CloseAudioDevice(playbackDeviceId);
}
end:
return 0;
}