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 ECHO_ASSERT(pOsSupport ); 91 92 m_pOsSupport = pOsSupport; // Ptr to OS Support methods & data 93 94 m_wFlags = ECHOGALS_FLAG_BADBOARD; 95 96 m_dwLockedSampleRate = 44100; 97 98 } // CEchoGals::CEchoGals() 99 100 101 //=========================================================================== 102 // 103 // Destructor 104 // 105 //=========================================================================== 106 107 CEchoGals::~CEchoGals() 108 { 109 // 110 // Free stuff 111 // 112 delete m_pDspCommObject; // This powers down the DSP 113 114 // 115 // Clean up the ducks 116 // 117 WORD i; 118 119 for (i = 0; i < ECHO_MAXAUDIOPIPES; i++) 120 { 121 if (NULL != m_DaffyDucks[i]) 122 delete m_DaffyDucks[i]; 123 } 124 125 // 126 // Clean up the mixer client list 127 // 128 while (NULL != m_pMixerClients) 129 { 130 ECHO_MIXER_CLIENT *pDeadClient; 131 132 pDeadClient = m_pMixerClients; 133 m_pMixerClients = pDeadClient->pNext; 134 OsFreeNonPaged(pDeadClient); 135 } 136 137 ECHO_DEBUGPRINTF( ( "CEchoGals::~CEchoGals() is toast!\n" ) ); 138 139 } // CEchoGals::~CEchoGals() 140 141 142 143 144 /**************************************************************************** 145 146 CEchoGals setup and hardware initialization 147 148 ****************************************************************************/ 149 150 //=========================================================================== 151 // 152 // AssignResources does just what you'd expect. 153 // 154 // Note that pvSharedMemory is a logical pointer - that is, the driver 155 // will dereference this pointer to access the memory-mapped regisers on 156 // the DSP. The caller needs to take the physical address from the PCI 157 // config space and map it. 158 // 159 //=========================================================================== 160 161 ECHOSTATUS CEchoGals::AssignResources 162 ( 163 PVOID pvSharedMemory, // Ptr to DSP registers 164 const char* pszCardName // Caller gets from registry 165 ) 166 { 167 // 168 // Use ECHO_ASSERT(to be sure this isn't called twice! 169 // 170 ECHO_ASSERT(NULL == m_pvSharedMemory ); 171 172 // 173 // Check and store the parameters 174 // 175 ECHO_ASSERT(pvSharedMemory ); 176 if ( NULL == pszCardName ) 177 { 178 return( ECHOSTATUS_BAD_CARD_NAME ); 179 } 180 m_pvSharedMemory = pvSharedMemory; // Shared memory addr assigned by PNP 181 182 // 183 // Copy card name & make sure we don't overflow our buffer 184 // 185 strncpy( m_szCardInstallName, pszCardName, ECHO_MAXNAMELEN-1 ); 186 m_szCardInstallName[ ECHO_MAXNAMELEN-1 ] = 0; 187 188 return ECHOSTATUS_OK; 189 190 } // ECHOSTATUS CEchoGals::AssignResources 191 192 193 //=========================================================================== 194 // 195 // InitHw is device-specific and so does nothing here; it is overridden 196 // in the derived classes. 197 // 198 // The correct sequence is: 199 // 200 // Construct the appropriate CEchoGals-derived object for the card 201 // Call AssignResources 202 // Call InitHw 203 // 204 //=========================================================================== 205 206 ECHOSTATUS CEchoGals::InitHw() 207 { 208 // 209 // Use ECHO_ASSERT to be sure AssignResources was called! 210 // 211 ECHO_ASSERT(m_pvSharedMemory ); 212 213 return ECHOSTATUS_OK; 214 215 } // ECHOSTATUS CEchoGals::InitHw() 216 217 218 //=========================================================================== 219 // 220 // This method initializes classes to control the mixer controls for 221 // the busses and pipes. This is a protected method; it is called 222 // from each of the CEchoGals derived classes once the DSP is up 223 // and running. 224 // 225 //=========================================================================== 226 227 ECHOSTATUS CEchoGals::InitLineLevels() 228 { 229 ECHOSTATUS Status = ECHOSTATUS_OK; 230 WORD i; 231 232 m_fMixerDisabled = TRUE; 233 234 if ( (NULL == GetDspCommObject()) || 235 (GetDspCommObject()->IsBoardBad() ) ) 236 { 237 return ECHOSTATUS_DSP_DEAD; 238 } 239 240 // 241 // Do output busses first since output pipes & monitors 242 // depend on output bus values 243 // 244 for ( i = 0; i < GetNumBussesOut(); i++ ) 245 { 246 m_BusOutLineLevels[ i ].Init( i, this ); 247 } 248 249 Status = m_PipeOutCtrl.Init(this); 250 if (ECHOSTATUS_OK != Status) 251 return Status; 252 253 Status = m_MonitorCtrl.Init(this); 254 if (ECHOSTATUS_OK != Status) 255 return Status; 256 257 for ( i = 0; i < GetNumBussesIn(); i++ ) 258 { 259 m_BusInLineLevels[ i ].Init( i, this ); 260 } 261 262 m_fMixerDisabled = FALSE; 263 264 return Status; 265 266 } // ECHOSTATUS CEchoGals::InitLineLevels() 267 268 269 270 271 /****************************************************************************** 272 273 CEchoGals interrupt handler functions 274 275 ******************************************************************************/ 276 277 //=========================================================================== 278 // 279 // This isn't the interrupt handler itself; rather, the OS-specific layer 280 // of the driver has an interrupt handler that calls this function. 281 // 282 //=========================================================================== 283 284 ECHOSTATUS CEchoGals::ServiceIrq(BOOL &fMidiReceived) 285 { 286 CDspCommObject *pDCO; 287 288 // 289 // Read the DSP status register and see if this DSP 290 // generated this interrupt 291 // 292 fMidiReceived = FALSE; 293 294 pDCO = GetDspCommObject(); 295 if ( pDCO->GetStatusReg() & CHI32_STATUS_IRQ ) 296 { 297 298 #ifdef MIDI_SUPPORT 299 300 // 301 // If this was a MIDI input interrupt, get the MIDI input data 302 // 303 DWORD dwMidiInCount; 304 305 pDCO->ReadMidi( 0, dwMidiInCount ); // The count is at index 0 306 if ( 0 != dwMidiInCount ) 307 { 308 m_MidiIn.ServiceIrq(); 309 fMidiReceived = TRUE; 310 } 311 312 #endif // MIDI_SUPPORT 313 314 // 315 // Clear the hardware interrupt 316 // 317 pDCO->AckInt(); 318 319 return ECHOSTATUS_OK; 320 } 321 322 // 323 // This interrupt line must be shared 324 // 325 /* 326 ECHO_DEBUGPRINTF( ("CEchoGals::ServiceIrq() %s\tInterrupt not ours!\n", 327 GetDeviceName()) ); 328 */ 329 330 return ECHOSTATUS_IRQ_NOT_OURS; 331 332 } // ECHOSTATUS CEchoGals::ServiceIrq() 333 334 335 336 337 /**************************************************************************** 338 339 Character strings for the ECHOSTATUS return values - 340 useful for debugging. 341 342 ****************************************************************************/ 343 344 // 345 // pStatusStrs is used if you want to print out a friendlier version of 346 // the various ECHOSTATUS codes. 347 // 348 const char * pStatusStrs[ECHOSTATUS_LAST] = 349 { 350 "ECHOSTATUS_OK", 351 "ECHOSTATUS_BAD_FORMAT", 352 "ECHOSTATUS_BAD_BUFFER_SIZE", 353 "ECHOSTATUS_CANT_OPEN", 354 "ECHOSTATUS_CANT_CLOSE", 355 "ECHOSTATUS_CHANNEL_NOT_OPEN", 356 "ECHOSTATUS_BUSY", 357 "ECHOSTATUS_BAD_LEVEL", 358 "ECHOSTATUS_NO_MIDI", 359 "ECHOSTATUS_CLOCK_NOT_SUPPORTED", 360 "ECHOSTATUS_CLOCK_NOT_AVAILABLE", 361 "ECHOSTATUS_BAD_CARDID", 362 "ECHOSTATUS_NOT_SUPPORTED", 363 "ECHOSTATUS_BAD_NOTIFY_SIZE", 364 "ECHOSTATUS_INVALID_PARAM", 365 "ECHOSTATUS_NO_MEM", 366 "ECHOSTATUS_NOT_SHAREABLE", 367 "ECHOSTATUS_FIRMWARE_LOADED", 368 "ECHOSTATUS_DSP_DEAD", 369 "ECHOSTATUS_DSP_TIMEOUT", 370 "ECHOSTATUS_INVALID_CHANNEL", 371 "ECHOSTATUS_CHANNEL_ALREADY_OPEN", 372 "ECHOSTATUS_DUCK_FULL", 373 "ECHOSTATUS_INVALID_INDEX", 374 "ECHOSTATUS_BAD_CARD_NAME", 375 "ECHOSTATUS_IRQ_NOT_OURS", 376 "", 377 "", 378 "", 379 "", 380 "", 381 "ECHOSTATUS_BUFFER_OVERFLOW", 382 "ECHOSTATUS_OPERATION_CANCELED", 383 "ECHOSTATUS_EVENT_NOT_OPEN", 384 "ECHOSTATUS_ASIC_NOT_LOADED" 385 "ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED", 386 "ECHOSTATUS_RESERVED", 387 "ECHOSTATUS_BAD_COOKIE", 388 "ECHOSTATUS_MIXER_DISABLED", 389 "ECHOSTATUS_NO_SUPER_INTERLEAVE", 390 "ECHOSTATUS_DUCK_NOT_WRAPPED" 391 }; 392 393 394 395 // *** CEchoGals.cpp *** 396 397 398 399 400 401 402