#include #include #include /* * 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; }