/** * \brief Negative tests around enumeration and naming of audio devices. * * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName */ int audio_enumerateAndNameAudioDevicesNegativeTests() { int ret; int t; int i, j, no, nc; const char *name; /* Get number of devices. */ no = SDL_GetNumAudioDevices(0); nc = SDL_GetNumAudioDevices(1); /* Invalid device index when getting name */ for (t=0; t<2; t++) { /* Negative device index */ i = -1; name = SDL_GetAudioDeviceName(i, t); AssertTrue(name == NULL, "SDL_GetAudioDeviceName(%i, %i): returned a name, should return NULL", i, t); /* Device index past range */ for (j=0; j<3; j++) { i = (t) ? nc+j : no+j; name = SDL_GetAudioDeviceName(i, t); AssertTrue(name == NULL, "SDL_GetAudioDeviceName(%i, %i): returned a name, should return NULL", i, t); } /* Capture index past capture range but within output range */ if ((no>0) && (no>nc) && (t==1)) { i = no-1; name = SDL_GetAudioDeviceName(i, t); AssertTrue(name == NULL, "SDL_GetAudioDeviceName(%i, %i): returned a name, should return NULL", i, t); } } }
/** * \brief Enumerate and name available audio devices (output and capture). * * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName */ int audio_enumerateAndNameAudioDevices() { int t, tt; int i, n, nn; const char *name, *nameAgain; /* Iterate over types: t=0 output device, t=1 input/capture device */ for (t=0; t<2; t++) { /* Get number of devices. */ n = SDL_GetNumAudioDevices(t); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(%i)", t); SDLTest_Log("Number of %s devices < 0, reported as %i", (t) ? "capture" : "output", n); SDLTest_AssertCheck(n >= 0, "Validate result is >= 0, got: %i", n); /* Variation of non-zero type */ if (t==1) { tt = t + SDLTest_RandomIntegerInRange(1,10); nn = SDL_GetNumAudioDevices(tt); SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", tt, n, nn); nn = SDL_GetNumAudioDevices(-tt); SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", -tt, n, nn); } /* List devices. */ if (n>0) { for (i=0; i<n; i++) { name = SDL_GetAudioDeviceName(i, t); SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, t); if (name != NULL) { SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, t, name); if (t==1) { /* Also try non-zero type */ tt = t + SDLTest_RandomIntegerInRange(1,10); nameAgain = SDL_GetAudioDeviceName(i, tt); SDLTest_AssertCheck(nameAgain != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, tt); if (nameAgain != NULL) { SDLTest_AssertCheck(nameAgain[0] != '\0', "Verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, tt, nameAgain); SDLTest_AssertCheck(SDL_strcmp(name, nameAgain)==0, "Verify SDL_GetAudioDeviceName(%i, %i) and SDL_GetAudioDeviceName(%i %i) return the same string", i, t, i, tt); } } } } } } return TEST_COMPLETED; }
void audio_populate_devices() { if (gAudioDevices != NULL) free(gAudioDevices); gAudioDeviceCount = SDL_GetNumAudioDevices(SDL_FALSE); if (gAudioDeviceCount <= 0) return; audio_device *systemAudioDevices = malloc(gAudioDeviceCount * sizeof(audio_device)); for (int i = 0; i < gAudioDeviceCount; i++) { const char *utf8Name = SDL_GetAudioDeviceName(i, SDL_FALSE); if (utf8Name == NULL) utf8Name = language_get_string(5511); safe_strcpy(systemAudioDevices[i].name, utf8Name, AUDIO_DEVICE_NAME_SIZE); } #ifndef __LINUX__ gAudioDeviceCount++; gAudioDevices = malloc(gAudioDeviceCount * sizeof(audio_device)); safe_strcpy(gAudioDevices[0].name, language_get_string(5510), AUDIO_DEVICE_NAME_SIZE); memcpy(&gAudioDevices[1], systemAudioDevices, (gAudioDeviceCount - 1) * sizeof(audio_device)); #else gAudioDevices = malloc(gAudioDeviceCount * sizeof(audio_device)); memcpy(gAudioDevices, systemAudioDevices, gAudioDeviceCount * sizeof(audio_device)); #endif // __LINUX__ free(systemAudioDevices); }
SdlAudioSink::SdlAudioSink(const AudioSource &source, int device_id) : bytes_per_sample(source.BytesPerSample()), ring_buf(RINGBUF_POWER, source.BytesPerSample()), position_sample_count(0), source_out(false), state(Audio::State::STOPPED) { const char *name = SDL_GetAudioDeviceName(device_id, 0); if (name == nullptr) { throw ConfigError(std::string("invalid device id: ") + std::to_string(device_id)); } SDL_AudioSpec want; SDL_zero(want); want.freq = source.SampleRate(); want.format = FORMATS[static_cast<int>(source.OutputSampleFormat())]; want.channels = source.ChannelCount(); want.callback = &SDLCallback; want.userdata = (void *)this; SDL_AudioSpec have; SDL_zero(have); this->device = SDL_OpenAudioDevice(name, 0, &want, &have, 0); if (this->device == 0) { throw ConfigError(std::string("couldn't open device: ") + SDL_GetError()); } }
static int lua_getAudioDevices(lutok::state& state){ state.new_table(); for (int capturing=0; capturing<2; capturing++){ state.push_string( (capturing == 0) ? "playback" : "capture"); state.new_table(); int ii=1; for (int i=0; i<SDL_GetNumAudioDevices(capturing); i++){ const char * name = SDL_GetAudioDeviceName( i, capturing); if (name){ state.push_integer(ii++); state.new_table(); state.push_literal("id"); state.push_integer(i); state.set_table(); state.push_literal("name"); state.push_string(name); state.set_table(); state.set_table(); } } state.set_table(); } return 1; }
bool SDLSoundInit() { if (audioid) return true; if (SDL_InitSubSystem(SDL_INIT_AUDIO)) return false; int count = SDL_GetNumAudioDevices(0); for (int i = 0; i < count; ++i) { Output(OUTPUT_INFO, "Audio device %d: %s", i, SDL_GetAudioDeviceName(i, 0)); } SDL_zero(playbackspec); playbackspec.freq = 44100; playbackspec.format = AUDIO_S16SYS; playbackspec.channels = 1; playbackspec.samples = 1024; playbackspec.callback = SDLAudioCallback; playbackspec.userdata = nullptr; SDL_AudioSpec obtained; audioid = SDL_OpenAudioDevice(nullptr, 0, &playbackspec, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); return !!audioid; }
static void iteration() { SDL_Event e; SDL_AudioDeviceID dev; while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { done = 1; } else if (e.type == SDL_AUDIODEVICEADDED) { const char *name = SDL_GetAudioDeviceName(e.adevice.which, 0); SDL_Log("New %s audio device: %s\n", e.adevice.iscapture ? "capture" : "output", name); if (!e.adevice.iscapture) { positions[posindex] = 0; spec.userdata = &positions[posindex++]; spec.callback = fillerup; dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0); if (!dev) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError()); } else { SDL_Log("Opened '%s' as %u\n", name, (unsigned int) dev); SDL_PauseAudioDevice(dev, 0); } } } else if (e.type == SDL_AUDIODEVICEREMOVED) { dev = (SDL_AudioDeviceID) e.adevice.which; SDL_Log("%s device %u removed.\n", e.adevice.iscapture ? "capture" : "output", (unsigned int) dev); SDL_CloseAudioDevice(dev); } } }
std::vector<std::string> AudioManager::get_devices() { std::vector<std::string> device_list; auto num_devices = SDL_GetNumAudioDevices(0); for (int i = 0; i < num_devices; i++) { device_list.push_back(SDL_GetAudioDeviceName(i, 0)); } return device_list; }
/** * \brief Enumerate and name available audio devices (output and capture). * * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName */ int audio_enumerateAndNameAudioDevices() { int ret; int t, tt; int i, n, nn; const char *name, *nameAgain; /* Iterate over types: t=0 output device, t=1 input/capture device */ for (t=0; t<2; t++) { /* Get number of devices. */ n = SDL_GetNumAudioDevices(t); AssertTrue(n>=0, "Number of %s devices < 0, reported as %i: %s", (t) ? "output" : "capture", n, SDL_GetError()); /* Variation of non-zero type */ if (t==1) { tt = t + RandomIntegerInRange(1,10); nn = SDL_GetNumAudioDevices(tt); AssertTrue(n==nn, "SDL_GetNumAudioDevices(%i) : expected same number of audio devices %i, got %i", tt, n, nn); nn = SDL_GetNumAudioDevices(-tt); AssertTrue(n==nn, "SDL_GetNumAudioDevices(%i) : expected same number of audio devices %i, got %i", -tt, n, nn); } /* List devices. */ if (n>0) { for (i=0; i<n; i++) { name = SDL_GetAudioDeviceName(i, t); AssertTrue(name != NULL, "SDL_GetAudioDeviceName(%i, %i): returned NULL name", i, t); AssertTrue(strlen(name)>0, "SDL_GetAudioDeviceName(%i, %i): returned empty name string", i, t); if (t==1) { /* Also try non-zero type */ nameAgain = SDL_GetAudioDeviceName(i, tt); AssertTrue(nameAgain != NULL, "SDL_GetAudioDeviceName(%i, %i): returned NULL name", i, tt); AssertTrue(strlen(nameAgain)>0, "SDL_GetAudioDeviceName(%i, %i): returned empty name string", i, tt); AssertTrue(strcmp(name, nameAgain)==0, "SDL_GetAudioDeviceName(%i, %i): returned unexpected name string %s, expected %s", i, tt, nameAgain, name); } } } } }
static int S_CaptureDriverInit (int sampleRate) { SDL_AudioDeviceID inputdevid = 0; SDL_AudioSpec desired, obtained; int ret = 0; const char *requested_device = NULL; if (SDL_WasInit (SDL_INIT_AUDIO) == 0) ret = SDL_InitSubSystem (SDL_INIT_AUDIO); if (ret == -1) { Con_Printf ("Couldn't initialize SDL audio: %s\n", SDL_GetError ()); return false; } memset (&desired, 0, sizeof (desired)); desired.freq = sampleRate; desired.samples = 64; desired.format = AUDIO_S16LSB; desired.channels = 1; /* Make audiodevice list start from index 1 so that 0 can be system default */ if (s_inputdevice.integer > 0) { requested_device = SDL_GetAudioDeviceName (s_inputdevice.integer - 1, 0); } if ((inputdevid = SDL_OpenAudioDevice (requested_device, 1, &desired, &obtained, 0)) <= 0) { Com_Printf ("sound: couldn't open SDL audio: %s\n", SDL_GetError ()); if (requested_device != NULL) { Com_Printf ("sound: retrying with default audio device\n"); if ((inputdevid = SDL_OpenAudioDevice (NULL, 1, &desired, &obtained, 0)) <= 0) { Com_Printf ("sound: failure again, aborting...\n"); return 0; } Cvar_LatchedSet (&s_inputdevice, "0"); } } if (obtained.format != AUDIO_S16LSB) { Com_Printf ("SDL audio format %d unsupported.\n", obtained.format); SDL_CloseAudioDevice (inputdevid); inputdevid = 0; return 0; } if (obtained.channels != 1 && obtained.channels != 2) { Com_Printf ("SDL audio channels %d unsupported.\n", obtained.channels); SDL_CloseAudioDevice (inputdevid); inputdevid = 0; return 0; } Com_Printf ("Using SDL audio capture driver: %s @ %d Hz (samplerate %d)\n", SDL_GetCurrentAudioDriver (), obtained.freq, obtained.samples); SDL_PauseAudioDevice (inputdevid, 0); return inputdevid; }
static int lua_SDL_GetAudioDeviceName(lutok::state& state){ const char * name = SDL_GetAudioDeviceName( state.to_integer(1), (state.to_boolean(2)) ? 1 : 0); if (name){ state.push_string(name); return 1; }else{ return 0; } }
/** * \brief Locks and unlocks open audio device. * * \sa https://wiki.libsdl.org/SDL_LockAudioDevice * \sa https://wiki.libsdl.org/SDL_UnlockAudioDevice */ int audio_lockUnlockOpenAudioDevice() { int i; int count; char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; /* Get number of devices. */ count = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ device = (char *)SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; /* Set standard desired spec */ desired.freq=22050; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=4096; desired.callback=_audio_testCallback; desired.userdata=NULL; /* Open device */ id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); if (id > 1) { /* Lock to protect callback */ SDL_LockAudioDevice(id); SDLTest_AssertPass("SDL_LockAudioDevice(%i)", id); /* Simulate callback processing */ SDL_Delay(10); SDLTest_Log("Simulate callback processing - delay"); /* Unlock again */ SDL_UnlockAudioDevice(id); SDLTest_AssertPass("SDL_UnlockAudioDevice(%i)", id); /* Close device again */ SDL_CloseAudioDevice(id); SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); } } } else { SDLTest_Log("No devices to test with"); } return TEST_COMPLETED; }
static void SND_DeviceList(void) { int i, count = SDL_GetNumAudioDevices(qfalse); Com_Printf("Printing audio device list. Number of devices: %i\n\n", count); for (i = 0; i < count; ++i) { Com_Printf(" Audio device %d: %s\n", i, SDL_GetAudioDeviceName(i, 0)); } }
/** * \brief Opens, checks current connected status, and closes a device. * * \sa https://wiki.libsdl.org/SDL_AudioDeviceConnected */ int audio_openCloseAudioDeviceConnected() { int result = -1; int i; int count; char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; /* Get number of devices. */ count = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ device = (char *)SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; /* Set standard desired spec */ desired.freq=22050; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=4096; desired.callback=_audio_testCallback; desired.userdata=NULL; /* Open device */ id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >1, got: %i", id); if (id > 1) { /* TODO: enable test code when function is available in SDL2 */ #ifdef AUDIODEVICECONNECTED_DEFINED /* Get connected status */ result = SDL_AudioDeviceConnected(id); SDLTest_AssertPass("Call to SDL_AudioDeviceConnected()"); #endif SDLTest_AssertCheck(result == 1, "Verify returned value; expected: 1; got: %i", result); /* Close device again */ SDL_CloseAudioDevice(id); SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); } } } else { SDLTest_Log("No devices to test with"); } return TEST_COMPLETED; }
static void test_multi_audio() { int keep_going = 1; int i; if (devcount > 64) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Too many devices (%d), clamping to 64...\n", devcount); devcount = 64; } spec.callback = play_through_once; SDL_memset(cbd, '\0', sizeof(cbd)); SDL_Log("playing on all devices...\n"); for (i = 0; i < devcount; i++) { const char *devname = SDL_GetAudioDeviceName(i, 0); spec.userdata = &cbd[i]; cbd[i].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0); if (cbd[i].dev == 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d failed: %s\n", i, SDL_GetError()); } } for (i = 0; i < devcount; i++) { if (cbd[i].dev) { SDL_PauseAudioDevice(cbd[i].dev, 0); } } #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, 0, 1); #else while (keep_going) { keep_going = 0; for (i = 0; i < devcount; i++) { if ((cbd[i].dev) && (!cbd[i].done)) { keep_going = 1; } } SDL_Delay(100); } #endif for (i = 0; i < devcount; i++) { if (cbd[i].dev) { SDL_PauseAudioDevice(cbd[i].dev, 1); SDL_CloseAudioDevice(cbd[i].dev); } } SDL_Log("All done!\n"); }
/** * \brief Opens, checks current audio status, and closes a device. * * \sa https://wiki.libsdl.org/SDL_GetAudioStatus */ int audio_openCloseAndGetAudioStatus() { SDL_AudioStatus result; int i; int count; char *device; SDL_AudioDeviceID id; SDL_AudioSpec desired, obtained; /* Get number of devices. */ count = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); if (count > 0) { for (i = 0; i < count; i++) { /* Get device name */ device = (char *)SDL_GetAudioDeviceName(i, 0); SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); if (device == NULL) return TEST_ABORTED; /* Set standard desired spec */ desired.freq=22050; desired.format=AUDIO_S16SYS; desired.channels=2; desired.samples=4096; desired.callback=_audio_testCallback; desired.userdata=NULL; /* Open device */ id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); if (id > 1) { /* Check device audio status */ result = SDL_GetAudioDeviceStatus(id); SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus()"); SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED, "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i", SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result); /* Close device again */ SDL_CloseAudioDevice(id); SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); } } } else { SDLTest_Log("No devices to test with"); } return TEST_COMPLETED; }
/** * \brief Negative tests around enumeration and naming of audio devices. * * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName */ int audio_enumerateAndNameAudioDevicesNegativeTests() { int t; int i, j, no, nc; const char *name; /* Get number of devices. */ no = SDL_GetNumAudioDevices(0); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); nc = SDL_GetNumAudioDevices(1); SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(1)"); /* Invalid device index when getting name */ for (t=0; t<2; t++) { /* Negative device index */ i = SDLTest_RandomIntegerInRange(-10,-1); name = SDL_GetAudioDeviceName(i, t); SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result NULL, expected NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); /* Device index past range */ for (j=0; j<3; j++) { i = (t) ? nc+j : no+j; name = SDL_GetAudioDeviceName(i, t); SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); } /* Capture index past capture range but within output range */ if ((no>0) && (no>nc) && (t==1)) { i = no-1; name = SDL_GetAudioDeviceName(i, t); SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); } } return TEST_COMPLETED; }
/* static */ std::vector<std::pair<int, std::string>> SdlAudioSink::GetDevicesInfo() { std::vector<std::pair<int, std::string>> list; // The 0 in SDL_GetNumAudioDevices tells SDL we want playback devices. int is = SDL_GetNumAudioDevices(0); for (int i = 0; i < is; i++) { const char *n = SDL_GetAudioDeviceName(i, 0); if (n != nullptr) list.emplace_back(i, std::string(n)); } return list; }
/** * @brief Prints available devices. */ static int audio_printDevices( int iscapture ) { int i, n; /* Get number of devices. */ n = SDL_GetNumAudioDevices(iscapture); SDL_ATprintVerbose( 1, "%d %s Audio Devices\n", n, iscapture ? "Capture" : "Output" ); /* List devices. */ for (i=0; i<n; i++) { SDL_ATprintVerbose( 1, " %d) %s\n", i+1, SDL_GetAudioDeviceName( i, iscapture ) ); } return 0; }
static qboolean QDECL SDL_Enumerate(void (QDECL *cb) (const char *drivername, const char *devicecode, const char *readablename)) { #if SDL_MAJOR_VERSION >= 2 int max, i; if(SSDL_InitAudio()) { max = SDL_GetNumAudioDevices(false); for (i = 0; i < max; i++) { const char *devname = SDL_GetAudioDeviceName(i, false); if (devname) cb(SDRVNAME, devname, va("SDL (%s)", devname)); } } return true; #else return false; #endif }
vsSoundSystem::vsSoundSystem() { s_instance = this; vsLog(" ++ Initialising mixer"); // if ( Mix_OpenAudio( MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024 ) ) #if !TARGET_OS_IPHONE if ( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 1024 ) ) vsLog(" !! Mix_OpenAudio: %s", Mix_GetError()); int numtimesopened, frequency, channels; Uint16 format; numtimesopened=Mix_QuerySpec(&frequency, &format, &channels); if(!numtimesopened) { vsLog(" !! Mix_QuerySpec: %s",Mix_GetError()); } else { const char *format_str="Unknown"; switch(format) { case AUDIO_U8: format_str="U8"; break; case AUDIO_S8: format_str="S8"; break; case AUDIO_U16LSB: format_str="U16LSB"; break; case AUDIO_S16LSB: format_str="S16LSB"; break; case AUDIO_U16MSB: format_str="U16MSB"; break; case AUDIO_S16MSB: format_str="S16MSB"; break; } vsLog(" ++ audio frequency=%dHz format=%s channels=%d", frequency, format_str, channels); } const char * soundDriver = SDL_GetAudioDeviceName(0, 0); if ( soundDriver ) vsLog(" ++ Sound playing using %s.", soundDriver); else vsLog(" ?? No sound driver reported by SDL_AudioDriverName."); m_channelCount = Mix_AllocateChannels(32); // get ourselves 32 channels for sound effects. That's pretty realistic for a SNES-era console. m_maxChannelsInUse = 0; m_channelsInUse = 0; Mix_ChannelFinished( &vsSoundSystem::ChannelFinished ); #endif }
static void print_devices(int iscapture) { const char *typestr = ((iscapture) ? "capture" : "output"); int n = SDL_GetNumAudioDevices(iscapture); SDL_Log("%s devices:\n", typestr); if (n == -1) SDL_Log(" Driver can't detect specific %s devices.\n\n", typestr); else if (n == 0) SDL_Log(" No %s devices found.\n\n", typestr); else { int i; for (i = 0; i < n; i++) { SDL_Log(" %s\n", SDL_GetAudioDeviceName(i, iscapture)); } SDL_Log("\n"); } }
void Audio_init () { SDL_AudioSpec want; want.freq = 44100; want.format = AUDIO_S16LSB; want.channels = 2; want.samples = 2048; want.callback = Audio_mixer; want.userdata = NULL; if (App_get_option_IV("info")) { int i; printf("Audio devices:\n"); for (i = 0; i < SDL_GetNumAudioDevices(0); i++) { const char* name = SDL_GetAudioDeviceName(i, 0); printf("\t%s\n", name); } const char* cur = SDL_GetCurrentAudioDriver(); printf("Current audio driver:\n\t%s\n", cur); printf("Audio drivers:\n"); for (i = 0; i < SDL_GetNumAudioDrivers(); i++) { const char* name = SDL_GetAudioDriver(i); printf("\t%s\n", name); } } _audio.device = SDL_OpenAudioDevice(NULL, 0, &want, &_audio.spec, SDL_AUDIO_ALLOW_ANY_CHANGE); if (_audio.device <= 0) error("Could not open audio device"); if (!App_get_option_IV("mute")) _audio.volume = SDL_MIX_MAXVOLUME; (void)SDL_AtomicSet(&_audio.playback_rate, 1); SDL_PauseAudioDevice(_audio.device, 0); }
bool AudioSystem::VInitialize() { m_pMainChannel = new AudioMixer(); if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { LOG_ERR("AudioSystem > Failed to initialize SDL Audio system."); return false; } // list audio devices for (int i = 0; i < SDL_GetNumAudioDevices(0); ++i) { LOG("Audio Device ", i, ": ", SDL_GetAudioDeviceName(i, 0)); } // acquire the audio device and spec SDL_AudioSpec wanted; SDL_zero(wanted); wanted.freq = 48000; wanted.format = AUDIO_F32; wanted.channels = 2; wanted.samples = 4096; wanted.callback = EmptyAudioCallback; wanted.userdata = m_pMainChannel; m_audioDevID = SDL_OpenAudioDevice(nullptr, 0, &wanted, &m_audioSpec, SDL_AUDIO_ALLOW_ANY_CHANGE); if (m_audioDevID == 0) { LOG_ERR("AudioSystem failed to obtain audio device spec! ", SDL_GetError()); } else { // start playing audio SDL_PauseAudioDevice(m_audioDevID, 0); } return true; }
static void print_devices(int iscapture) { const char *typestr = ((iscapture) ? "capture" : "output"); int n = SDL_GetNumAudioDevices(iscapture); SDL_Log("Found %d %s device%s:\n", n, typestr, n != 1 ? "s" : ""); if (n == -1) SDL_Log(" Driver can't detect specific %s devices.\n\n", typestr); else if (n == 0) SDL_Log(" No %s devices found.\n\n", typestr); else { int i; for (i = 0; i < n; i++) { const char *name = SDL_GetAudioDeviceName(i, iscapture); if (name != NULL) SDL_Log(" %d: %s\n", i, name); else SDL_Log(" %d Error: %s\n", i, SDL_GetError()); } SDL_Log("\n"); } }
int main(int argc, char *argv[]) { AVFormatContext *pFormatCtx = NULL; int i, videoStream, audioStream; AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec = NULL; AVFrame *pFrame = NULL; AVPacket packet; int frameFinished; //float aspect_ratio; AVCodecContext *aCodecCtx = NULL; AVCodec *aCodec = NULL; //SDL_Overlay *bmp = NULL; //SDL_Surface *screen = NULL; SDL_Window *m_pWindow = NULL; SDL_Renderer *m_pRenderer = NULL; SDL_Rect rect; SDL_Event event; SDL_AudioSpec wanted_spec, spec; //struct SwsContext *sws_ctx = NULL; AVDictionary *videoOptionsDict = NULL; AVDictionary *audioOptionsDict = NULL; if(argc < 2) { fprintf(stderr, "Usage: test <file>\n"); exit(1); } // Register all formats and codecs av_register_all(); if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); exit(1); } // Open video file if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0) return -1; // Couldn't open file // Retrieve stream information if(avformat_find_stream_info(pFormatCtx, NULL)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error av_dump_format(pFormatCtx, 0, argv[1], 0); // Find the first video stream videoStream=-1; audioStream=-1; for(i=0; i<pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO && videoStream < 0) { videoStream=i; // printf("video stream:%d",i); } if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO && audioStream < 0) { audioStream=i; // printf("audio stream:%d",i); } } // for(i=0; i<pFormatCtx->nb_streams; i++) { // if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { // printf("video stream:%d\n",i); // } // if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO ) { // printf("audio stream:%d\n",i); // } // } if(videoStream==-1) return -1; // Didn't find a video stream if(audioStream==-1) return -1; aCodecCtx=pFormatCtx->streams[audioStream]->codec; int count = SDL_GetNumAudioDevices(0); for (int i = 0; i < count; ++i) { SDL_Log("Audio device %d: %s", i, SDL_GetAudioDeviceName(i, 0)); } // Set audio settings from codec info wanted_spec.freq = aCodecCtx->sample_rate; wanted_spec.format = AUDIO_S16SYS; wanted_spec.channels = aCodecCtx->channels; wanted_spec.silence = 0; wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE; wanted_spec.callback = audio_callback; wanted_spec.userdata = aCodecCtx; // if(SDL_OpenAudio(&wanted_spec, &spec) < 0) // { // fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError()); // return -1; // } SDL_AudioDeviceID dev; dev = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &spec, SDL_AUDIO_ALLOW_FORMAT_CHANGE); if(dev == 0) { fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError()); } else { if(wanted_spec.format != spec.format){ fprintf(stderr, "We didn't get AUDIO_S16SYS audio format.\n"); return -1; } } aCodec = avcodec_find_decoder(aCodecCtx->codec_id); if(!aCodec) { fprintf(stderr, "Unsupported codec!\n"); return -1; } avcodec_open2(aCodecCtx, aCodec, &audioOptionsDict); // audio_st = pFormatCtx->streams[index] packet_queue_init(&audioq); //SDL_PauseAudio(0); SDL_PauseAudioDevice(dev,0); // Get a pointer to the codec context for the video stream pCodecCtx=pFormatCtx->streams[videoStream]->codec; // Find the decoder for the video stream pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { fprintf(stderr, "Unsupported codec!\n"); return -1; // Codec not found } // Open codec if(avcodec_open2(pCodecCtx, pCodec, &videoOptionsDict)<0) return -1; // Could not open codec // Allocate video frame pFrame=av_frame_alloc(); AVFrame* m_pFrameYUV = av_frame_alloc(); //int t_alloc_ret = av_image_alloc(m_pFrameYUV->data,m_pFrameYUV->linesize,pCodecCtx->width,pCodecCtx->height,AV_PIX_FMT_YUV420P,1); // int t_size0 = avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->coded_width, pCodecCtx->coded_height); // int t_size1 = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->coded_width, pCodecCtx->coded_height,1); //uint8_t * out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->coded_width, pCodecCtx->coded_height)); uint8_t * out_buffer = (uint8_t *)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)); //avpicture_fill((AVPicture *)m_pFrameYUV , out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->coded_width, pCodecCtx->coded_height); av_image_fill_arrays(m_pFrameYUV->data , m_pFrameYUV->linesize, out_buffer,AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height,1); struct SwsContext *img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,pCodecCtx->sw_pix_fmt, pCodecCtx->width, pCodecCtx->height,AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); // Make a screen to put our video //#ifndef __DARWIN__ // screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0); //#else // screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0); //#endif // // // if(!screen) { // fprintf(stderr, "SDL: could not set video mode - exiting\n"); // exit(1); // } // Allocate a place to put our YUV image on that screen // bmp = SDL_CreateYUVOverlay(pCodecCtx->width, // pCodecCtx->height, // SDL_YV12_OVERLAY, // screen); // Make a screen to put our video m_pWindow = SDL_CreateWindow("test windows", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,pCodecCtx->width, pCodecCtx->height,SDL_WINDOW_SHOWN); if(!m_pWindow) { printf("SDL: could not create window - exiting:%s\n",SDL_GetError()); return -1; } m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0); SDL_RenderClear(m_pRenderer); SDL_Texture *m_pSdlTexture = SDL_CreateTexture(m_pRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height); rect.x = 0; rect.y = 0; rect.w = pCodecCtx->width; rect.h = pCodecCtx->height; // Read frames and save first five frames to disk i=0; while(av_read_frame(pFormatCtx, &packet)>=0) { // Is this a packet from the video stream? if(packet.stream_index==videoStream) { // Decode video frame avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); // Did we get a video frame? if(frameFinished) { //SDL_LockTexture(m_pSdlTexture, &rect, m_pFrameYUV->data, m_pFrameYUV->linesize); //SDL_LockYUVOverlay(bmp); // AVPicture pict; // pict.data[0] = bmp->pixels[0]; // pict.data[1] = bmp->pixels[2]; // pict.data[2] = bmp->pixels[1]; // // pict.linesize[0] = bmp->pitches[0]; // pict.linesize[1] = bmp->pitches[2]; // pict.linesize[2] = bmp->pitches[1]; // Convert the image into YUV format that SDL uses // sws_scale // ( // sws_ctx, // (uint8_t const * const *)pFrame->data, // pFrame->linesize, // 0, // pCodecCtx->height, // pict.data, // pict.linesize // ); sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, m_pFrameYUV->data, m_pFrameYUV->linesize); //SDL_UnlockYUVOverlay(bmp); // SDL_UnlockTexture(m_pSdlTexture); SDL_UpdateYUVTexture(m_pSdlTexture, &rect, m_pFrameYUV->data[0], m_pFrameYUV->linesize[0], m_pFrameYUV->data[1], m_pFrameYUV->linesize[1], m_pFrameYUV->data[2], m_pFrameYUV->linesize[2]); // rect.x = 0; // rect.y = 0; // rect.w = pCodecCtx->width; // rect.h = pCodecCtx->height; //SDL_DisplayYUVOverlay(bmp, &rect); SDL_RenderClear( m_pRenderer );//this line seems nothing to do SDL_RenderCopy( m_pRenderer, m_pSdlTexture, NULL, &rect); SDL_RenderPresent(m_pRenderer); SDL_Delay(38); // av_free_packet(&packet); av_packet_unref(&packet); } } else if(packet.stream_index==audioStream) { packet_queue_put(&audioq, &packet); } else { // av_free_packet(&packet); av_packet_unref(&packet); } // Free the packet that was allocated by av_read_frame SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: quit = 1; SDL_Quit(); exit(0); break; default: break; } } // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file avformat_close_input(&pFormatCtx); return 0; }
int main(int argc, char **argv) { /* (argv[1] == NULL means "open default device.") */ const char *devname = argv[1]; SDL_AudioSpec wanted; int devcount; int i; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); /* Load the SDL library */ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); return (1); } window = SDL_CreateWindow("testaudiocapture", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0); renderer = SDL_CreateRenderer(window, -1, 0); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); devcount = SDL_GetNumAudioDevices(SDL_TRUE); for (i = 0; i < devcount; i++) { SDL_Log(" Capture device #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE)); } SDL_zero(wanted); wanted.freq = 44100; wanted.format = AUDIO_F32SYS; wanted.channels = 1; wanted.samples = 4096; wanted.callback = NULL; SDL_zero(spec); /* DirectSound can fail in some instances if you open the same hardware for both capture and output and didn't open the output end first, according to the docs, so if you're doing something like this, always open your capture devices second in case you land in those bizarre circumstances. */ SDL_Log("Opening default playback device...\n"); devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE); if (!devid_out) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!\n", SDL_GetError()); SDL_Quit(); exit(1); } SDL_Log("Opening capture device %s%s%s...\n", devname ? "'" : "", devname ? devname : "[[default]]", devname ? "'" : ""); devid_in = SDL_OpenAudioDevice(argv[1], SDL_TRUE, &spec, &spec, 0); if (!devid_in) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for capture: %s!\n", SDL_GetError()); SDL_Quit(); exit(1); } SDL_Log("Ready! Hold down mouse or finger to record!\n"); #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, 0, 1); #else while (1) { loop(); SDL_Delay(16); } #endif return 0; }
static int BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) { const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); SDL_AudioFormat format = 0; audio_info_t info; /* We don't care what the devname is...we'll try to open anything. */ /* ...but default to first name in the list... */ if (devname == NULL) { devname = SDL_GetAudioDeviceName(0, iscapture); if (devname == NULL) { SDL_SetError("No such audio device"); return 0; } } /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { SDL_OutOfMemory(); return 0; } SDL_memset(this->hidden, 0, (sizeof *this->hidden)); /* Open the audio device */ this->hidden->audio_fd = open(devname, flags, 0); if (this->hidden->audio_fd < 0) { SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); return 0; } AUDIO_INITINFO(&info); /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(&this->spec); /* Set to play mode */ info.mode = AUMODE_PLAY; if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) { BSDAUDIO_CloseDevice(this); SDL_SetError("Couldn't put device into play mode"); return 0; } AUDIO_INITINFO(&info); for (format = SDL_FirstAudioFormat(this->spec.format); format; format = SDL_NextAudioFormat()) { switch (format) { case AUDIO_U8: info.play.encoding = AUDIO_ENCODING_ULINEAR; info.play.precision = 8; break; case AUDIO_S8: info.play.encoding = AUDIO_ENCODING_SLINEAR; info.play.precision = 8; break; case AUDIO_S16LSB: info.play.encoding = AUDIO_ENCODING_SLINEAR_LE; info.play.precision = 16; break; case AUDIO_S16MSB: info.play.encoding = AUDIO_ENCODING_SLINEAR_BE; info.play.precision = 16; break; case AUDIO_U16LSB: info.play.encoding = AUDIO_ENCODING_ULINEAR_LE; info.play.precision = 16; break; case AUDIO_U16MSB: info.play.encoding = AUDIO_ENCODING_ULINEAR_BE; info.play.precision = 16; break; default: continue; } if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) { break; } } if (!format) { BSDAUDIO_CloseDevice(this); SDL_SetError("No supported encoding for 0x%x", this->spec.format); return 0; } this->spec.format = format; AUDIO_INITINFO(&info); info.play.channels = this->spec.channels; if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) { this->spec.channels = 1; } AUDIO_INITINFO(&info); info.play.sample_rate = this->spec.freq; info.blocksize = this->spec.size; info.hiwat = 5; info.lowat = 3; (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info); (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info); this->spec.freq = info.play.sample_rate; /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { BSDAUDIO_CloseDevice(this); SDL_OutOfMemory(); return 0; } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); BSDAUDIO_Status(this); /* We're ready to rock and roll. :-) */ return (0); }
static int SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); SDL_AudioFormat format = 0; audio_info_t info; /* We don't care what the devname is...we'll try to open anything. */ /* ...but default to first name in the list... */ if (devname == NULL) { devname = SDL_GetAudioDeviceName(0, iscapture); if (devname == NULL) { return SDL_SetError("No such audio device"); } } /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } SDL_memset(this->hidden, 0, (sizeof *this->hidden)); /* Open the audio device */ this->hidden->audio_fd = open(devname, flags, 0); if (this->hidden->audio_fd < 0) { return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); } #ifdef AUDIO_SETINFO int enc; #endif int desired_freq = this->spec.freq; /* Determine the audio parameters from the AudioSpec */ switch (SDL_AUDIO_BITSIZE(this->spec.format)) { case 8: { /* Unsigned 8 bit audio data */ this->spec.format = AUDIO_U8; #ifdef AUDIO_SETINFO enc = AUDIO_ENCODING_LINEAR8; #endif } break; case 16: { /* Signed 16 bit audio data */ this->spec.format = AUDIO_S16SYS; #ifdef AUDIO_SETINFO enc = AUDIO_ENCODING_LINEAR; #endif } break; default: { /* !!! FIXME: fallback to conversion on unsupported types! */ return SDL_SetError("Unsupported audio format"); } } this->hidden->audio_fmt = this->spec.format; this->hidden->ulaw_only = 0; /* modern Suns do support linear audio */ #ifdef AUDIO_SETINFO for (;;) { audio_info_t info; AUDIO_INITINFO(&info); /* init all fields to "no change" */ /* Try to set the requested settings */ info.play.sample_rate = this->spec.freq; info.play.channels = this->spec.channels; info.play.precision = (enc == AUDIO_ENCODING_ULAW) ? 8 : this->spec.format & 0xff; info.play.encoding = enc; if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) { /* Check to be sure we got what we wanted */ if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { return SDL_SetError("Error getting audio parameters: %s", strerror(errno)); } if (info.play.encoding == enc && info.play.precision == (this->spec.format & 0xff) && info.play.channels == this->spec.channels) { /* Yow! All seems to be well! */ this->spec.freq = info.play.sample_rate; break; } } switch (enc) { case AUDIO_ENCODING_LINEAR8: /* unsigned 8bit apparently not supported here */ enc = AUDIO_ENCODING_LINEAR; this->spec.format = AUDIO_S16SYS; break; /* try again */ case AUDIO_ENCODING_LINEAR: /* linear 16bit didn't work either, resort to µ-law */ enc = AUDIO_ENCODING_ULAW; this->spec.channels = 1; this->spec.freq = 8000; this->spec.format = AUDIO_U8; this->hidden->ulaw_only = 1; break; default: /* oh well... */ return SDL_SetError("Error setting audio parameters: %s", strerror(errno)); } } #endif /* AUDIO_SETINFO */ this->hidden->written = 0; /* We can actually convert on-the-fly to U-Law */ if (this->hidden->ulaw_only) { this->spec.freq = desired_freq; this->hidden->fragsize = (this->spec.samples * 1000) / (this->spec.freq / 8); this->hidden->frequency = 8; this->hidden->ulaw_buf = (Uint8 *) SDL_malloc(this->hidden->fragsize); if (this->hidden->ulaw_buf == NULL) { return SDL_OutOfMemory(); } this->spec.channels = 1; } else { this->hidden->fragsize = this->spec.samples; this->hidden->frequency = this->spec.freq / 1000; } #ifdef DEBUG_AUDIO fprintf(stderr, "Audio device %s U-Law only\n", this->hidden->ulaw_only ? "is" : "is not"); fprintf(stderr, "format=0x%x chan=%d freq=%d\n", this->spec.format, this->spec.channels, this->spec.freq); #endif /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); /* Allocate mixing buffer */ this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size); if (this->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); /* We're ready to rock and roll. :-) */ return 0; }
static int DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); int format; int value; int frag_spec; SDL_AudioFormat test_format; /* We don't care what the devname is...we'll try to open anything. */ /* ...but default to first name in the list... */ if (devname == NULL) { devname = SDL_GetAudioDeviceName(0, iscapture); if (devname == NULL) { return SDL_SetError("No such audio device"); } } /* Make sure fragment size stays a power of 2, or OSS fails. */ /* I don't know which of these are actually legal values, though... */ if (this->spec.channels > 8) this->spec.channels = 8; else if (this->spec.channels > 4) this->spec.channels = 4; else if (this->spec.channels > 2) this->spec.channels = 2; /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); /* Open the audio device */ this->hidden->audio_fd = open(devname, flags, 0); if (this->hidden->audio_fd < 0) { return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); } /* Make the file descriptor use blocking i/o with fcntl() */ { long ctlflags; ctlflags = fcntl(this->hidden->audio_fd, F_GETFL); ctlflags &= ~O_NONBLOCK; if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) { return SDL_SetError("Couldn't set audio blocking mode"); } } /* Get a list of supported hardware formats */ if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { perror("SNDCTL_DSP_GETFMTS"); return SDL_SetError("Couldn't get audio format list"); } /* Try for a closest match on audio format */ format = 0; for (test_format = SDL_FirstAudioFormat(this->spec.format); !format && test_format;) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch (test_format) { case AUDIO_U8: if (value & AFMT_U8) { format = AFMT_U8; } break; case AUDIO_S16LSB: if (value & AFMT_S16_LE) { format = AFMT_S16_LE; } break; case AUDIO_S16MSB: if (value & AFMT_S16_BE) { format = AFMT_S16_BE; } break; #if 0 /* * These formats are not used by any real life systems so they are not * needed here. */ case AUDIO_S8: if (value & AFMT_S8) { format = AFMT_S8; } break; case AUDIO_U16LSB: if (value & AFMT_U16_LE) { format = AFMT_U16_LE; } break; case AUDIO_U16MSB: if (value & AFMT_U16_BE) { format = AFMT_U16_BE; } break; #endif default: format = 0; break; } if (!format) { test_format = SDL_NextAudioFormat(); } } if (format == 0) { return SDL_SetError("Couldn't find any hardware audio formats"); } this->spec.format = test_format; /* Set the audio format */ value = format; if ((ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) { perror("SNDCTL_DSP_SETFMT"); return SDL_SetError("Couldn't set audio format"); } /* Set the number of channels of output */ value = this->spec.channels; if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) { perror("SNDCTL_DSP_CHANNELS"); return SDL_SetError("Cannot set the number of channels"); } this->spec.channels = value; /* Set the DSP frequency */ value = this->spec.freq; if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) { perror("SNDCTL_DSP_SPEED"); return SDL_SetError("Couldn't set audio frequency"); } this->spec.freq = value; /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(&this->spec); /* Determine the power of two of the fragment size */ for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec); if ((0x01U << frag_spec) != this->spec.size) { return SDL_SetError("Fragment size must be a power of two"); } frag_spec |= 0x00020000; /* two fragments, for low latency */ /* Set the audio buffering parameters */ #ifdef DEBUG_AUDIO fprintf(stderr, "Requesting %d fragments of size %d\n", (frag_spec >> 16), 1 << (frag_spec & 0xFFFF)); #endif if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) { perror("SNDCTL_DSP_SETFRAGMENT"); } #ifdef DEBUG_AUDIO { audio_buf_info info; ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info); fprintf(stderr, "fragments = %d\n", info.fragments); fprintf(stderr, "fragstotal = %d\n", info.fragstotal); fprintf(stderr, "fragsize = %d\n", info.fragsize); fprintf(stderr, "bytes = %d\n", info.bytes); } #endif /* Allocate mixing buffer */ if (!iscapture) { this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); } /* We're ready to rock and roll. :-) */ return 0; }