MMRESULT AllocateSoundDeviceInstance( OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance) { PSOUND_DEVICE_INSTANCE NewInstance; VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance ); /* Allocate memory for the new instance */ NewInstance = AllocateStruct(SOUND_DEVICE_INSTANCE); if ( ! NewInstance ) return MMSYSERR_NOMEM; /* Use default frame size */ NewInstance->FrameSize = SOUND_KERNEL_BUFFER_SIZE; /* Use default buffer count */ NewInstance->BufferCount = SOUND_KERNEL_BUFFER_COUNT; /* Provide the caller with the new instance pointer */ *SoundDeviceInstance = NewInstance; return MMSYSERR_NOERROR; }
MMRESULT CreateSoundThread( OUT PSOUND_THREAD* Thread) { MMRESULT Result; PSOUND_THREAD NewThread; VALIDATE_MMSYS_PARAMETER( Thread ); NewThread = AllocateStruct(SOUND_THREAD); if ( ! NewThread ) return MMSYSERR_NOMEM; /* Prepare the events we'll be using to sync. everything */ Result = CreateSoundThreadEvents(&NewThread->Events.Ready, &NewThread->Events.Request, &NewThread->Events.Done); if ( ! MMSUCCESS(Result) ) { FreeMemory(NewThread); return TranslateInternalMmResult(Result); } SND_TRACE(L"Creating a sound thread\n"); NewThread->Handle = CreateThread(NULL, 0, &SoundThreadMain, (LPVOID) NewThread, CREATE_SUSPENDED, NULL); /* Something went wrong, bail out! */ if ( NewThread->Handle == INVALID_HANDLE_VALUE ) { SND_ERR(L"Sound thread creation failed!\n"); DestroySoundThreadEvents(NewThread->Events.Ready, NewThread->Events.Request, NewThread->Events.Done); FreeMemory(NewThread); return Win32ErrorToMmResult(GetLastError()); } /* Wake the thread up */ if ( ResumeThread(NewThread->Handle) == -1 ) { SND_ERR(L"Failed to resume thread!\n"); CloseHandle(NewThread->Handle); DestroySoundThreadEvents(NewThread->Events.Ready, NewThread->Events.Request, NewThread->Events.Done); FreeMemory(NewThread); return Win32ErrorToMmResult(GetLastError()); } /* If all is well we can now give the thread to the caller */ *Thread = NewThread; return MMSYSERR_NOERROR; }