1 // **************************************************************************** 2 // 3 // CEchoGals.cpp 4 // 5 // Implementation file for the CEchoGals driver class. 6 // Set editor tabs to 3 for your viewing pleasure. 7 // 8 // ---------------------------------------------------------------------------- 9 // 10 // This file is part of Echo Digital Audio's generic driver library. 11 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005 12 // All rights reserved 13 // www.echoaudio.com 14 // 15 // This library is free software; you can redistribute it and/or 16 // modify it under the terms of the GNU Lesser General Public 17 // License as published by the Free Software Foundation; either 18 // version 2.1 of the License, or (at your option) any later version. 19 // 20 // This library is distributed in the hope that it will be useful, 21 // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 // Lesser General Public License for more details. 24 // 25 // You should have received a copy of the GNU Lesser General Public 26 // License along with this library; if not, write to the Free Software 27 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 // 29 // **************************************************************************** 30 31 #include "CEchoGals.h" 32 33 34 /**************************************************************************** 35 36 CEchoGals construction and destruction 37 38 ****************************************************************************/ 39 40 //=========================================================================== 41 // 42 // Overload new & delete so memory for this object is allocated 43 // from non-paged memory. 44 // 45 //=========================================================================== 46 47 PVOID CEchoGals::operator new( size_t Size ) 48 { 49 PVOID pMemory; 50 ECHOSTATUS Status; 51 52 Status = OsAllocateNonPaged(Size,&pMemory); 53 54 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) 55 { 56 ECHO_DEBUGPRINTF(("CEchoGals::operator new - memory allocation failed\n")); 57 58 pMemory = NULL; 59 } 60 else 61 { 62 memset( pMemory, 0, Size ); 63 } 64 65 return pMemory; 66 67 } // PVOID CEchoGals::operator new( size_t Size ) 68 69 70 VOID CEchoGals::operator delete( PVOID pVoid ) 71 { 72 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 73 { 74 ECHO_DEBUGPRINTF(("CEchoGals::operator delete memory free failed\n")); 75 } 76 } // VOID CEchoGals::operator delete( PVOID pVoid ) 77 78 79 //=========================================================================== 80 // 81 // Constructor 82 // 83 //=========================================================================== 84 85 CEchoGals::CEchoGals 86 ( 87 PCOsSupport pOsSupport 88 ) 89 { 90 INT32 i; 91 92 ASSERT( pOsSupport ); 93 94 m_pOsSupport = pOsSupport; // Ptr to OS Support methods & data 95 96 m_wFlags = ECHOGALS_FLAG_BADBOARD; 97 98 for ( i = 0; i < ECHO_MAXAUDIOPIPES; i++ ) 99 { 100 m_wBytesPerSample[ i ] = 1; 101 } 102 103 m_dwLockedSampleRate = 44100; 104 105 } // CEchoGals::CEchoGals() 106 107 108 //=========================================================================== 109 // 110 // Destructor 111 // 112 //=========================================================================== 113 114 CEchoGals::~CEchoGals() 115 { 116 // 117 // Free stuff 118 // 119 delete m_pDspCommObject; // This powers down the DSP 120 121 // 122 // Clean up the ducks 123 // 124 WORD i; 125 126 for (i = 0; i < ECHO_MAXAUDIOPIPES; i++) 127 { 128 if (NULL != m_DaffyDucks[i]) 129 delete m_DaffyDucks[i]; 130 } 131 132 // 133 // Clean up the mixer client list 134 // 135 while (NULL != m_pMixerClients) 136 { 137 ECHO_MIXER_CLIENT *pDeadClient; 138 139 pDeadClient = m_pMixerClients; 140 m_pMixerClients = pDeadClient->pNext; 141 OsFreeNonPaged(pDeadClient); 142 } 143 144 ECHO_DEBUGPRINTF( ( "CEchoGals::~CEchoGals() is toast!\n" ) ); 145 146 } // CEchoGals::~CEchoGals() 147 148 149 150 151 /**************************************************************************** 152 153 CEchoGals setup and hardware initialization 154 155 ****************************************************************************/ 156 157 //=========================================================================== 158 // 159 // AssignResources does just what you'd expect. 160 // 161 // Note that pvSharedMemory is a logical pointer - that is, the driver 162 // will dereference this pointer to access the memory-mapped regisers on 163 // the DSP. The caller needs to take the physical address from the PCI 164 // config space and map it. 165 // 166 //=========================================================================== 167 168 ECHOSTATUS CEchoGals::AssignResources 169 ( 170 PVOID pvSharedMemory, // Ptr to DSP registers 171 PCHAR pszCardName // Caller gets from registry 172 ) 173 { 174 // 175 // Use ASSERT to be sure this isn't called twice! 176 // 177 ASSERT( NULL == m_pvSharedMemory ); 178 179 // 180 // Check and store the parameters 181 // 182 ASSERT( pvSharedMemory ); 183 if ( NULL == pszCardName ) 184 { 185 return( ECHOSTATUS_BAD_CARD_NAME ); 186 } 187 m_pvSharedMemory = pvSharedMemory; // Shared memory addr assigned by PNP 188 189 // 190 // Copy card name & make sure we don't overflow our buffer 191 // 192 strncpy( m_szCardInstallName, pszCardName, ECHO_MAXNAMELEN-1 ); 193 m_szCardInstallName[ ECHO_MAXNAMELEN-1 ] = 0; 194 195 return ECHOSTATUS_OK; 196 197 } // ECHOSTATUS CEchoGals::AssignResources 198 199 200 //=========================================================================== 201 // 202 // InitHw is device-specific and so does nothing here; it is overridden 203 // in the derived classes. 204 // 205 // The correct sequence is: 206 // 207 // Construct the appropriate CEchoGals-derived object for the card 208 // Call AssignResources 209 // Call InitHw 210 // 211 //=========================================================================== 212 213 ECHOSTATUS CEchoGals::InitHw() 214 { 215 // 216 // Use ASSERT to be sure AssignResources was called! 217 // 218 ASSERT( m_pvSharedMemory ); 219 220 return ECHOSTATUS_OK; 221 222 } // ECHOSTATUS CEchoGals::InitHw() 223 224 225 //=========================================================================== 226 // 227 // This method initializes classes to control the mixer controls for 228 // the busses and pipes. This is a protected method; it is called 229 // from each of the CEchoGals derived classes once the DSP is up 230 // and running. 231 // 232 //=========================================================================== 233 234 ECHOSTATUS CEchoGals::InitLineLevels() 235 { 236 ECHOSTATUS Status = ECHOSTATUS_OK; 237 WORD i; 238 239 m_fMixerDisabled = TRUE; 240 241 if ( (NULL == GetDspCommObject()) || 242 (GetDspCommObject()->IsBoardBad() ) ) 243 { 244 return ECHOSTATUS_DSP_DEAD; 245 } 246 247 // 248 // Do output busses first since output pipes & monitors 249 // depend on output bus values 250 // 251 for ( i = 0; i < GetNumBussesOut(); i++ ) 252 { 253 m_BusOutLineLevels[ i ].Init( i, this ); 254 } 255 256 Status = m_PipeOutCtrl.Init(this); 257 if (ECHOSTATUS_OK != Status) 258 return Status; 259 260 Status = m_MonitorCtrl.Init(this); 261 if (ECHOSTATUS_OK != Status) 262 return Status; 263 264 for ( i = 0; i < GetNumBussesIn(); i++ ) 265 { 266 m_BusInLineLevels[ i ].Init( i, this ); 267 } 268 269 m_fMixerDisabled = FALSE; 270 271 return Status; 272 273 } // ECHOSTATUS CEchoGals::InitLineLevels() 274 275 276 277 278 /****************************************************************************** 279 280 CEchoGals interrupt handler functions 281 282 ******************************************************************************/ 283 284 //=========================================================================== 285 // 286 // This isn't the interrupt handler itself; rather, the OS-specific layer 287 // of the driver has an interrupt handler that calls this function. 288 // 289 //=========================================================================== 290 291 ECHOSTATUS CEchoGals::ServiceIrq(BOOL &fMidiReceived) 292 { 293 CDspCommObject *pDCO; 294 295 // 296 // Read the DSP status register and see if this DSP 297 // generated this interrupt 298 // 299 fMidiReceived = FALSE; 300 301 pDCO = GetDspCommObject(); 302 if ( pDCO->GetStatusReg() & CHI32_STATUS_IRQ ) 303 { 304 305 #ifdef MIDI_SUPPORT 306 307 // 308 // If this was a MIDI input interrupt, get the MIDI input data 309 // 310 DWORD dwMidiInCount; 311 312 pDCO->ReadMidi( 0, dwMidiInCount ); // The count is at index 0 313 if ( 0 != dwMidiInCount ) 314 { 315 m_MidiIn.ServiceIrq(); 316 fMidiReceived = TRUE; 317 } 318 319 #endif // MIDI_SUPPORT 320 321 // 322 // Clear the hardware interrupt 323 // 324 pDCO->AckInt(); 325 326 return ECHOSTATUS_OK; 327 } 328 329 // 330 // This interrupt line must be shared 331 // 332 /* 333 ECHO_DEBUGPRINTF( ("CEchoGals::ServiceIrq() %s\tInterrupt not ours!\n", 334 GetDeviceName()) ); 335 */ 336 337 return ECHOSTATUS_IRQ_NOT_OURS; 338 339 } // ECHOSTATUS CEchoGals::ServiceIrq() 340 341 342 343 344 /**************************************************************************** 345 346 Character strings for the ECHOSTATUS return values - 347 useful for debugging. 348 349 ****************************************************************************/ 350 351 // 352 // pStatusStrs is used if you want to print out a friendlier version of 353 // the various ECHOSTATUS codes. 354 // 355 char * pStatusStrs[ECHOSTATUS_LAST] = 356 { 357 "ECHOSTATUS_OK", 358 "ECHOSTATUS_BAD_FORMAT", 359 "ECHOSTATUS_BAD_BUFFER_SIZE", 360 "ECHOSTATUS_CANT_OPEN", 361 "ECHOSTATUS_CANT_CLOSE", 362 "ECHOSTATUS_CHANNEL_NOT_OPEN", 363 "ECHOSTATUS_BUSY", 364 "ECHOSTATUS_BAD_LEVEL", 365 "ECHOSTATUS_NO_MIDI", 366 "ECHOSTATUS_CLOCK_NOT_SUPPORTED", 367 "ECHOSTATUS_CLOCK_NOT_AVAILABLE", 368 "ECHOSTATUS_BAD_CARDID", 369 "ECHOSTATUS_NOT_SUPPORTED", 370 "ECHOSTATUS_BAD_NOTIFY_SIZE", 371 "ECHOSTATUS_INVALID_PARAM", 372 "ECHOSTATUS_NO_MEM", 373 "ECHOSTATUS_NOT_SHAREABLE", 374 "ECHOSTATUS_FIRMWARE_LOADED", 375 "ECHOSTATUS_DSP_DEAD", 376 "ECHOSTATUS_DSP_TIMEOUT", 377 "ECHOSTATUS_INVALID_CHANNEL", 378 "ECHOSTATUS_CHANNEL_ALREADY_OPEN", 379 "ECHOSTATUS_DUCK_FULL", 380 "ECHOSTATUS_INVALID_INDEX", 381 "ECHOSTATUS_BAD_CARD_NAME", 382 "ECHOSTATUS_IRQ_NOT_OURS", 383 "", 384 "", 385 "", 386 "", 387 "", 388 "ECHOSTATUS_BUFFER_OVERFLOW", 389 "ECHOSTATUS_OPERATION_CANCELED", 390 "ECHOSTATUS_EVENT_NOT_OPEN", 391 "ECHOSTATUS_ASIC_NOT_LOADED" 392 "ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED", 393 "ECHOSTATUS_RESERVED", 394 "ECHOSTATUS_BAD_COOKIE", 395 "ECHOSTATUS_MIXER_DISABLED", 396 "ECHOSTATUS_NO_SUPER_INTERLEAVE", 397 "ECHOSTATUS_DUCK_NOT_WRAPPED" 398 }; 399 400 401 402 // *** CEchoGals.cpp *** 403 404 405 406 407 408