172 lines
5.2 KiB
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;
|
|
}
|