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 47PVOID 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 70VOID 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 85CEchoGals::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 107CEchoGals::~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 161ECHOSTATUS CEchoGals::AssignResources 162( 163 PVOID pvSharedMemory, // Ptr to DSP registers 164 PCHAR 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 206ECHOSTATUS 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 227ECHOSTATUS 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 284ECHOSTATUS 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// 348char * 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