RageSound_ALSA9_Software::~RageSound_ALSA9_Software() { /* Signal the mixing thread to quit. */ shutdown = true; LOG->Trace("Shutting down mixer thread ..."); MixingThread.Wait(); LOG->Trace("Mixer thread shut down."); delete pcm; UnloadALSA(); }
RageSoundDriver_ALSA9_Software::~RageSoundDriver_ALSA9_Software() { if( m_MixingThread.IsCreated() ) { /* Signal the mixing thread to quit. */ m_bShutdown = true; LOG->Trace("Shutting down mixer thread ..."); m_MixingThread.Wait(); LOG->Trace("Mixer thread shut down."); } delete m_pPCM; UnloadALSA(); }
RageSoundDriver_ALSA9::~RageSoundDriver_ALSA9() { if( MixingThread.IsCreated() ) { /* Signal the mixing thread to quit. */ shutdown = true; LOG->Trace("Shutting down mixer thread ..."); MixingThread.Wait(); LOG->Trace("Mixer thread shut down."); } for(unsigned i = 0; i < stream_pool.size(); ++i) delete stream_pool[i]; UnloadALSA(); }
RString LoadALSA() { /* If /proc/asound/ doesn't exist, chances are we're on an OSS system. We shouldn't * touch ALSA at all, since many OSS systems have old, broken versions of ALSA lying * around; we're likely to crash if we go near it. Do this first, before loading * the ALSA library, since making any ALSA calls may load ALSA core modules. * * It's vaguely possible that a module autoloader would load the entire ALSA module set * on use, and this would prevent that from happening. I don't know if anyone actually * does that, though: they're often configured to load snd (the core module) if ALSA * devices are accessed, but hardware drivers are typically loaded on boot. */ if( !IsADirectory("/rootfs/proc/asound/") ) return "/proc/asound/ does not exist"; ASSERT( Handle == NULL ); Handle = dlopen( lib, RTLD_NOW ); if( Handle == NULL ) return ssprintf("dlopen(%s): %s", lib.c_str(), dlerror()); RString error; /* Eww. The "new" HW and SW API functions are really prefixed by __, * eg. __snd_pcm_hw_params_set_rate_near. */ #define FUNC(ret, name, proto) \ d##name = (name##_f) dlsym(Handle, "__" #name); \ if( !d##name ) { \ d##name = (name##_f) dlsym(Handle, #name); \ if( !d##name ) { \ error="Couldn't load symbol " #name; \ goto error; \ } \ } #include "ALSA9Functions.h" #undef FUNC return ""; error: UnloadALSA(); return error; }
RageSound_ALSA9_Software::RageSound_ALSA9_Software() { CString err = LoadALSA(); if( err != "" ) RageException::ThrowNonfatal("Driver unusable: %s", err.c_str()); try { shutdown = false; max_writeahead = safe_writeahead; CString sys; int vers; GetKernel( sys, vers ); LOG->Trace( "OS: %s ver %06i", sys.c_str(), vers ); if( sys == "Linux" && vers >= 20600 ) max_writeahead = max_writeahead_linux_26; if( PREFSMAN->m_iSoundWriteAhead ) max_writeahead = PREFSMAN->m_iSoundWriteAhead; pcm = new Alsa9Buf( Alsa9Buf::HW_DONT_CARE, channels ); samplerate = pcm->FindSampleRate( samplerate ); pcm->SetSampleRate( samplerate ); LOG->Info( "ALSA: Software mixing at %ihz", samplerate ); pcm->SetWriteahead( max_writeahead ); pcm->SetChunksize( max_writeahead / num_chunks ); pcm->LogParams(); StartDecodeThread(); MixingThread.SetName( "RageSound_ALSA9_Software" ); MixingThread.Create( MixerThread_start, this ); } catch(...) { UnloadALSA(); throw; } }