| 1 | /* $Id: waveinoutbase.cpp,v 1.4 2002-04-07 14:36:31 sandervl Exp $ */ | 
|---|
| 2 |  | 
|---|
| 3 | /* | 
|---|
| 4 | * Wave playback class (DART) | 
|---|
| 5 | * | 
|---|
| 6 | * Copyright 1998-2001 Sander van Leeuwen (sandervl@xs4all.nl) | 
|---|
| 7 | * | 
|---|
| 8 | * | 
|---|
| 9 | * Project Odin Software License can be found in LICENSE.TXT | 
|---|
| 10 | * | 
|---|
| 11 | * | 
|---|
| 12 | */ | 
|---|
| 13 |  | 
|---|
| 14 |  | 
|---|
| 15 | /**************************************************************************** | 
|---|
| 16 | * Includes                                                                 * | 
|---|
| 17 | ****************************************************************************/ | 
|---|
| 18 |  | 
|---|
| 19 |  | 
|---|
| 20 |  | 
|---|
| 21 | #define  INCL_BASE | 
|---|
| 22 | #define  INCL_OS2MM | 
|---|
| 23 | #include <os2wrap.h>   //Odin32 OS/2 api wrappers | 
|---|
| 24 | #include <os2mewrap.h> //Odin32 OS/2 MMPM/2 api wrappers | 
|---|
| 25 | #include <stdlib.h> | 
|---|
| 26 | #include <string.h> | 
|---|
| 27 | #define  OS2_ONLY | 
|---|
| 28 | #include <win32api.h> | 
|---|
| 29 | #include <wprocess.h> | 
|---|
| 30 |  | 
|---|
| 31 | #include "misc.h" | 
|---|
| 32 | #include "waveinoutbase.h" | 
|---|
| 33 |  | 
|---|
| 34 | #define DBG_LOCALLOG    DBG_waveinoutbase | 
|---|
| 35 | #include "dbglocal.h" | 
|---|
| 36 |  | 
|---|
| 37 |  | 
|---|
| 38 | /******************************************************************************/ | 
|---|
| 39 | /******************************************************************************/ | 
|---|
| 40 | WaveInOut::WaveInOut(LPWAVEFORMATEX pwfx, ULONG fdwOpen, ULONG nCallback, ULONG dwInstance) | 
|---|
| 41 | { | 
|---|
| 42 | next            = NULL; | 
|---|
| 43 | wavehdr         = NULL; | 
|---|
| 44 | curhdr          = NULL; | 
|---|
| 45 | ulError         = 0; | 
|---|
| 46 | State           = STATE_STOPPED; | 
|---|
| 47 | queuedbuffers   = 0; | 
|---|
| 48 |  | 
|---|
| 49 | BitsPerSample   = pwfx->wBitsPerSample; | 
|---|
| 50 | SampleRate      = pwfx->nSamplesPerSec; | 
|---|
| 51 | this->nChannels = pwfx->nChannels; | 
|---|
| 52 |  | 
|---|
| 53 | dprintf(("WaveInOutOpen: samplerate %d, numChan %d bps %d (%d), format %x", SampleRate, nChannels, BitsPerSample, pwfx->nBlockAlign, pwfx->wFormatTag)); | 
|---|
| 54 |  | 
|---|
| 55 | State    = STATE_STOPPED; | 
|---|
| 56 |  | 
|---|
| 57 | wmutex.enter(); | 
|---|
| 58 |  | 
|---|
| 59 | if(wave == NULL) { | 
|---|
| 60 | wave = this; | 
|---|
| 61 | } | 
|---|
| 62 | else { | 
|---|
| 63 | WaveInOut *dwave = wave; | 
|---|
| 64 |  | 
|---|
| 65 | while(dwave->next) { | 
|---|
| 66 | dwave = dwave->next; | 
|---|
| 67 | } | 
|---|
| 68 | dwave->next = this; | 
|---|
| 69 | } | 
|---|
| 70 | wmutex.leave(); | 
|---|
| 71 |  | 
|---|
| 72 | this->fdwOpen = fdwOpen; | 
|---|
| 73 | dwCallback    = nCallback; | 
|---|
| 74 | this->dwInstance = dwInstance; | 
|---|
| 75 | } | 
|---|
| 76 | /******************************************************************************/ | 
|---|
| 77 | /******************************************************************************/ | 
|---|
| 78 | WaveInOut::~WaveInOut() | 
|---|
| 79 | { | 
|---|
| 80 | wmutex.enter(); | 
|---|
| 81 |  | 
|---|
| 82 | State = STATE_STOPPED; | 
|---|
| 83 |  | 
|---|
| 84 | if(wave == this) { | 
|---|
| 85 | wave = this->next; | 
|---|
| 86 | } | 
|---|
| 87 | else { | 
|---|
| 88 | WaveInOut *dwave = wave; | 
|---|
| 89 |  | 
|---|
| 90 | while(dwave->next != this) { | 
|---|
| 91 | dwave = dwave->next; | 
|---|
| 92 | } | 
|---|
| 93 | dwave->next = this->next; | 
|---|
| 94 | } | 
|---|
| 95 | wmutex.leave(); | 
|---|
| 96 | } | 
|---|
| 97 | /******************************************************************************/ | 
|---|
| 98 | /******************************************************************************/ | 
|---|
| 99 | void WaveInOut::callback(UINT uMessage, DWORD dw1, DWORD dw2) | 
|---|
| 100 | { | 
|---|
| 101 | dprintf(("WINMM:WaveInOut::callback type %x (HDRVR h=%08xh, UINT uMessage=%08xh, DWORD dwUser=%08xh, DWORD dw1=%08xh, DWORD dw2=%08xh)\n", | 
|---|
| 102 | fdwOpen, this, uMessage, dwInstance, dw1, dw2)); | 
|---|
| 103 |  | 
|---|
| 104 | switch(fdwOpen & CALLBACK_TYPEMASK) { | 
|---|
| 105 | case CALLBACK_WINDOW: | 
|---|
| 106 | PostMessageA((HWND)dwCallback, uMessage, (WPARAM)this, dw1); | 
|---|
| 107 | break; | 
|---|
| 108 |  | 
|---|
| 109 | case CALLBACK_TASK: // == CALLBACK_THREAD | 
|---|
| 110 | PostThreadMessageA(dwCallback, uMessage, (WPARAM)this, dw1); | 
|---|
| 111 | break; | 
|---|
| 112 |  | 
|---|
| 113 | case CALLBACK_FUNCTION: | 
|---|
| 114 | { | 
|---|
| 115 | USHORT selTIB = GetFS(); // save current FS selector | 
|---|
| 116 | USHORT selCallback; | 
|---|
| 117 | LPDRVCALLBACK mthdCallback = (LPDRVCALLBACK)dwCallback; | 
|---|
| 118 |  | 
|---|
| 119 | selCallback = GetProcessTIBSel(); | 
|---|
| 120 |  | 
|---|
| 121 | //TODO: may not be very safe. perhaps we should allocate a new TIB for the DART thread or let another thread do the actual callback | 
|---|
| 122 | if(selCallback) | 
|---|
| 123 | { | 
|---|
| 124 | SetFS(selCallback);      // switch to callback win32 tib selector (stored in WaveInOutOpen) | 
|---|
| 125 |  | 
|---|
| 126 | //@@@PH 1999/12/28 Shockwave Flashes seem to make assumptions on a | 
|---|
| 127 | // specific stack layout. Do we have the correct calling convention here? | 
|---|
| 128 | mthdCallback((HDRVR)this, uMessage, dwInstance, dw1, dw2); | 
|---|
| 129 | SetFS(selTIB);           // switch back to the saved FS selector | 
|---|
| 130 | } | 
|---|
| 131 | else { | 
|---|
| 132 | dprintf(("WARNING: no valid selector of main thread available (process exiting); skipping WaveInOut notify")); | 
|---|
| 133 | } | 
|---|
| 134 | break; | 
|---|
| 135 | } | 
|---|
| 136 |  | 
|---|
| 137 | case CALLBACK_EVENT: | 
|---|
| 138 | SetEvent((HANDLE)dwCallback); | 
|---|
| 139 | break; | 
|---|
| 140 |  | 
|---|
| 141 | default: | 
|---|
| 142 | dprintf(("WARNING: Unknown callback type %x %x", fdwOpen, dwCallback)); | 
|---|
| 143 | break; | 
|---|
| 144 | } //switch | 
|---|
| 145 | dprintf2(("WINMM:WaveInOut::callback returned")); | 
|---|
| 146 | } | 
|---|
| 147 | /******************************************************************************/ | 
|---|
| 148 | /******************************************************************************/ | 
|---|
| 149 | BOOL WaveInOut::find(WaveInOut *dwave) | 
|---|
| 150 | { | 
|---|
| 151 | WaveInOut *curwave = wave; | 
|---|
| 152 |  | 
|---|
| 153 | while(curwave) { | 
|---|
| 154 | if(dwave == curwave) { | 
|---|
| 155 | return(TRUE); | 
|---|
| 156 | } | 
|---|
| 157 | curwave = curwave->next; | 
|---|
| 158 | } | 
|---|
| 159 |  | 
|---|
| 160 | dprintf2(("WINMM:WaveInOut not found!\n")); | 
|---|
| 161 | return(FALSE); | 
|---|
| 162 | } | 
|---|
| 163 | /******************************************************************************/ | 
|---|
| 164 | /******************************************************************************/ | 
|---|
| 165 | WaveInOut *WaveInOut::wave = NULL; | 
|---|
| 166 |  | 
|---|