1 // **************************************************************************** 2 // 3 // CLayla24.cpp 4 // 5 // Implementation file for the CLayla24 driver class. 6 // Set editor tabs to 3 for your viewing pleasure. 7 // 8 // Copyright Echo Digital Audio Corporation (c) 1998 - 2002 9 // All rights reserved 10 // www.echoaudio.com 11 // 12 // Permission is hereby granted, free of charge, to any person obtaining a 13 // copy of this software and associated documentation files (the 14 // "Software"), to deal with the Software without restriction, including 15 // without limitation the rights to use, copy, modify, merge, publish, 16 // distribute, sublicense, and/or sell copies of the Software, and to 17 // permit persons to whom the Software is furnished to do so, subject to 18 // the following conditions: 19 // 20 // - Redistributions of source code must retain the above copyright 21 // notice, this list of conditions and the following disclaimers. 22 // 23 // - Redistributions in binary form must reproduce the above copyright 24 // notice, this list of conditions and the following disclaimers in the 25 // documentation and/or other materials provided with the distribution. 26 // 27 // - Neither the name of Echo Digital Audio, nor the names of its 28 // contributors may be used to endorse or promote products derived from 29 // this Software without specific prior written permission. 30 // 31 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 32 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 33 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 34 // IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR 35 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 36 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 37 // SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. 38 // 39 // **************************************************************************** 40 41 #include "CLayla24.h" 42 43 44 /**************************************************************************** 45 46 Construction and destruction 47 48 ****************************************************************************/ 49 50 //=========================================================================== 51 // 52 // Overload new & delete so memory for this object is allocated 53 // from non-paged memory. 54 // 55 //=========================================================================== 56 57 PVOID CLayla24::operator new( size_t Size ) 58 { 59 PVOID pMemory; 60 ECHOSTATUS Status; 61 62 Status = OsAllocateNonPaged(Size,&pMemory); 63 64 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) 65 { 66 ECHO_DEBUGPRINTF(("CLayla24::operator new - memory allocation failed\n")); 67 68 pMemory = NULL; 69 } 70 else 71 { 72 memset( pMemory, 0, Size ); 73 } 74 75 return pMemory; 76 77 } // PVOID CLayla24::operator new( size_t Size ) 78 79 80 VOID CLayla24::operator delete( PVOID pVoid ) 81 { 82 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 83 { 84 ECHO_DEBUGPRINTF( ("CLayla24::operator delete memory free failed\n") ); 85 } 86 } // VOID CLayla24::operator delete( PVOID pVoid ) 87 88 89 //=========================================================================== 90 // 91 // Constructor and destructor 92 // 93 //=========================================================================== 94 95 CLayla24::CLayla24( PCOsSupport pOsSupport ) 96 : CEchoGals( pOsSupport ) 97 { 98 ECHO_DEBUGPRINTF( ( "CLayla24::CLayla24() is born!\n" ) ); 99 } // CLayla24::CLayla24() 100 101 102 CLayla24::~CLayla24() 103 { 104 ECHO_DEBUGPRINTF( ( "CLayla24::~CLayla24() is toast!\n" ) ); 105 } // CLayla24::~CLayla24() 106 107 108 109 110 /**************************************************************************** 111 112 Setup and hardware initialization 113 114 ****************************************************************************/ 115 116 //=========================================================================== 117 // 118 // Every card has an InitHw method 119 // 120 //=========================================================================== 121 122 ECHOSTATUS CLayla24::InitHw() 123 { 124 ECHOSTATUS Status; 125 WORD i; 126 127 // 128 // Call the base method 129 // 130 if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) ) 131 return Status; 132 133 // 134 // Create the DSP comm object 135 // 136 ASSERT( NULL == m_pDspCommObject ); 137 m_pDspCommObject = new CLayla24DspCommObject( (PDWORD) m_pvSharedMemory, 138 m_pOsSupport ); 139 if (NULL == m_pDspCommObject) 140 { 141 ECHO_DEBUGPRINTF(("CLayla24::InitHw - could not create DSP comm object\n")); 142 return ECHOSTATUS_NO_MEM; 143 } 144 145 // 146 // Load the DSP, the PCI card ASIC, and the external box ASIC 147 // 148 GetDspCommObject()->LoadFirmware(); 149 if ( GetDspCommObject()->IsBoardBad() ) 150 return ECHOSTATUS_DSP_DEAD; 151 152 // 153 // Clear the "bad board" flag; set the flags to indicate that 154 // Layla24 can handle super-interleave and supports the digital 155 // input auto-mute. 156 // 157 m_wFlags &= ~ECHOGALS_FLAG_BADBOARD; 158 m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK | 159 ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE; 160 161 // 162 // Must call this here after DSP is init to 163 // init gains and mutes 164 // 165 Status = InitLineLevels(); 166 if ( ECHOSTATUS_OK != Status ) 167 return Status; 168 169 // 170 // Initialize the MIDI input 171 // 172 Status = m_MidiIn.Init( this ); 173 if ( ECHOSTATUS_OK != Status ) 174 return Status; 175 176 177 // 178 // Set defaults for +4/-10 179 // 180 for (i = 0; i < GetFirstDigitalBusOut(); i++ ) 181 { 182 GetDspCommObject()-> 183 SetNominalLevel( i, FALSE ); // FALSE is +4 here 184 } 185 186 for ( i = 0; i < GetFirstDigitalBusIn(); i++ ) 187 { 188 GetDspCommObject()-> 189 SetNominalLevel( GetNumBussesOut() + i, FALSE ); 190 } 191 // 192 // Set the digital mode to S/PDIF RCA 193 // 194 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA ); 195 196 // 197 // Set the S/PDIF output format to "professional" 198 // 199 SetProfessionalSpdif( TRUE ); 200 201 // 202 // Get default sample rate from DSP 203 // 204 m_dwSampleRate = GetDspCommObject()->GetSampleRate(); 205 206 ECHO_DEBUGPRINTF( ( "CLayla24::InitHw()\n" ) ); 207 return Status; 208 209 } // ECHOSTATUS CLayla24::InitHw() 210 211 212 213 214 /**************************************************************************** 215 216 Informational methods 217 218 ****************************************************************************/ 219 220 //=========================================================================== 221 // 222 // Override GetCapabilities to enumerate unique capabilties for this card 223 // 224 //=========================================================================== 225 226 ECHOSTATUS CLayla24::GetCapabilities 227 ( 228 PECHOGALS_CAPS pCapabilities 229 ) 230 { 231 ECHOSTATUS Status; 232 WORD i; 233 234 Status = GetBaseCapabilities(pCapabilities); 235 236 if ( ECHOSTATUS_OK != Status ) 237 return Status; 238 239 // 240 // Add nominal level control to analog ins & outs 241 // 242 for (i = 0 ; i < GetFirstDigitalBusOut(); i++) 243 { 244 pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 245 } 246 247 for (i = 0 ; i < GetFirstDigitalBusIn(); i++) 248 { 249 pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 250 } 251 252 pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD | 253 ECHO_CLOCK_BIT_SPDIF | 254 ECHO_CLOCK_BIT_ADAT; 255 256 return Status; 257 258 } // ECHOSTATUS CLayla24::GetCapabilities 259 260 261 //=========================================================================== 262 // 263 // QueryAudioSampleRate is used to find out if this card can handle a 264 // given sample rate. 265 // 266 //=========================================================================== 267 268 ECHOSTATUS CLayla24::QueryAudioSampleRate 269 ( 270 DWORD dwSampleRate 271 ) 272 { 273 // 274 // Standard sample rates are allowed (like Mona & Layla24) 275 // 276 switch ( dwSampleRate ) 277 { 278 case 8000 : 279 case 11025 : 280 case 16000 : 281 case 22050 : 282 case 32000 : 283 case 44100 : 284 case 48000 : 285 goto qasr_ex; 286 287 case 88200 : 288 case 96000 : 289 290 // 291 // Double speed sample rates not allowed in ADAT mode 292 // 293 if ( DIGITAL_MODE_ADAT == GetDigitalMode() ) 294 { 295 ECHO_DEBUGPRINTF( 296 ("CLayla24::QueryAudioSampleRate() Sample rate must be < " 297 "50,000 Hz in ADAT mode\n") ); 298 return ECHOSTATUS_BAD_FORMAT; 299 } 300 goto qasr_ex; 301 } 302 303 // 304 // Any rate from 25000 to 50000 is allowed 305 // 306 if ( ( dwSampleRate >= 25000 ) && 307 ( dwSampleRate <= 50000 ) ) 308 goto qasr_ex; 309 310 // 311 // If not in ADAT mode, any rate from 50,000 to 100,000 is allowed 312 // 313 if ( DIGITAL_MODE_ADAT != GetDigitalMode() && 314 ( dwSampleRate >= 50000 ) && 315 ( dwSampleRate <= 100000 ) ) 316 goto qasr_ex; 317 318 ECHO_DEBUGPRINTF( 319 ("CLayla24::QueryAudioSampleRate() Sample rate must be >= 50,000 Hz" 320 " and <= 100,000 Hz and NOT in ADAT mode\n") ); 321 return ECHOSTATUS_BAD_FORMAT; 322 323 qasr_ex: 324 ECHO_DEBUGPRINTF( ( "CLayla24::QueryAudioSampleRate() %ld Hz OK\n", 325 dwSampleRate ) ); 326 return ECHOSTATUS_OK; 327 } // ECHOSTATUS CLayla24::QueryAudioSampleRate 328 329 330 //=========================================================================== 331 // 332 // GetInputClockDetect returns a bitmask consisting of all the input 333 // clocks currently connected to the hardware; this changes as the user 334 // connects and disconnects clock inputs. 335 // 336 // You should use this information to determine which clocks the user is 337 // allowed to select. 338 // 339 // Layla24 supports S/PDIF, word, and ADAT input clocks. 340 // 341 //=========================================================================== 342 343 ECHOSTATUS CLayla24::GetInputClockDetect(DWORD &dwClockDetectBits) 344 { 345 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) 346 { 347 ECHO_DEBUGPRINTF( ("CLayla24::GetInputClockDetect: DSP Dead!\n") ); 348 return ECHOSTATUS_DSP_DEAD; 349 } 350 351 // 352 // Map the DSP clock detect bits to the generic driver clock detect bits 353 // 354 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); 355 356 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL; 357 358 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF)) 359 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; 360 361 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT)) 362 dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT; 363 364 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD)) 365 dwClockDetectBits |= ECHO_CLOCK_BIT_WORD; 366 367 return ECHOSTATUS_OK; 368 369 } // GetInputClockDetect 370 371 372 // *** Layla24.cpp *** 373