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 // ---------------------------------------------------------------------------- 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 "CLayla24.h" 32 33 #define LAYLA24_ANALOG_OUTPUT_LATENCY 59 34 #define LAYLA24_ANALOG_INPUT_LATENCY 71 35 #define LAYLA24_DIGITAL_OUTPUT_LATENCY 32 36 #define LAYLA24_DIGITAL_INPUT_LATENCY 32 37 38 39 40 /**************************************************************************** 41 42 Construction and destruction 43 44 ****************************************************************************/ 45 46 //=========================================================================== 47 // 48 // Overload new & delete so memory for this object is allocated 49 // from non-paged memory. 50 // 51 //=========================================================================== 52 53 PVOID CLayla24::operator new( size_t Size ) 54 { 55 PVOID pMemory; 56 ECHOSTATUS Status; 57 58 Status = OsAllocateNonPaged(Size,&pMemory); 59 60 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) 61 { 62 ECHO_DEBUGPRINTF(("CLayla24::operator new - memory allocation failed\n")); 63 64 pMemory = NULL; 65 } 66 else 67 { 68 memset( pMemory, 0, Size ); 69 } 70 71 return pMemory; 72 73 } // PVOID CLayla24::operator new( size_t Size ) 74 75 76 VOID CLayla24::operator delete( PVOID pVoid ) 77 { 78 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 79 { 80 ECHO_DEBUGPRINTF( ("CLayla24::operator delete memory free failed\n") ); 81 } 82 } // VOID CLayla24::operator delete( PVOID pVoid ) 83 84 85 //=========================================================================== 86 // 87 // Constructor and destructor 88 // 89 //=========================================================================== 90 91 CLayla24::CLayla24( PCOsSupport pOsSupport ) 92 : CEchoGalsMTC( pOsSupport ) 93 { 94 ECHO_DEBUGPRINTF( ( "CLayla24::CLayla24() is born!\n" ) ); 95 96 m_wAnalogOutputLatency = LAYLA24_ANALOG_OUTPUT_LATENCY; 97 m_wAnalogInputLatency = LAYLA24_ANALOG_INPUT_LATENCY; 98 m_wDigitalOutputLatency = LAYLA24_DIGITAL_OUTPUT_LATENCY; 99 m_wDigitalInputLatency = LAYLA24_DIGITAL_INPUT_LATENCY; 100 101 } // CLayla24::CLayla24() 102 103 104 CLayla24::~CLayla24() 105 { 106 ECHO_DEBUGPRINTF( ( "CLayla24::~CLayla24() is toast!\n" ) ); 107 } // CLayla24::~CLayla24() 108 109 110 111 112 /**************************************************************************** 113 114 Setup and hardware initialization 115 116 ****************************************************************************/ 117 118 //=========================================================================== 119 // 120 // Every card has an InitHw method 121 // 122 //=========================================================================== 123 124 ECHOSTATUS CLayla24::InitHw() 125 { 126 ECHOSTATUS Status; 127 WORD i; 128 129 // 130 // Call the base method 131 // 132 if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) ) 133 return Status; 134 135 // 136 // Create the DSP comm object 137 // 138 ECHO_ASSERT(NULL == m_pDspCommObject ); 139 m_pDspCommObject = new CLayla24DspCommObject( (PDWORD) m_pvSharedMemory, 140 m_pOsSupport ); 141 if (NULL == m_pDspCommObject) 142 { 143 ECHO_DEBUGPRINTF(("CLayla24::InitHw - could not create DSP comm object\n")); 144 return ECHOSTATUS_NO_MEM; 145 } 146 147 // 148 // Load the DSP, the PCI card ASIC, and the external box ASIC 149 // 150 GetDspCommObject()->LoadFirmware(); 151 if ( GetDspCommObject()->IsBoardBad() ) 152 return ECHOSTATUS_DSP_DEAD; 153 154 // 155 // Clear the "bad board" flag; set the flags to indicate that 156 // Layla24 can handle super-interleave and supports the digital 157 // input auto-mute. 158 // 159 m_wFlags &= ~ECHOGALS_FLAG_BADBOARD; 160 m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK | 161 ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE; 162 163 // 164 // Must call this here after DSP is init to 165 // init gains and mutes 166 // 167 Status = InitLineLevels(); 168 if ( ECHOSTATUS_OK != Status ) 169 return Status; 170 171 // 172 // Initialize the MIDI input 173 // 174 Status = m_MidiIn.Init( this ); 175 if ( ECHOSTATUS_OK != Status ) 176 return Status; 177 178 179 // 180 // Set defaults for +4/-10 181 // 182 for (i = 0; i < GetFirstDigitalBusOut(); i++ ) 183 { 184 GetDspCommObject()-> 185 SetNominalLevel( i, FALSE ); // FALSE is +4 here 186 } 187 188 for ( i = 0; i < GetNumBussesIn(); i++ ) 189 { 190 GetDspCommObject()-> 191 SetNominalLevel( GetNumBussesOut() + i, FALSE ); 192 } 193 194 // 195 // Set the digital mode to S/PDIF RCA 196 // 197 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA ); 198 199 // 200 // Set the S/PDIF output format to "professional" 201 // 202 SetProfessionalSpdif( TRUE ); 203 204 // 205 // Get default sample rate from DSP 206 // 207 m_dwSampleRate = GetDspCommObject()->GetSampleRate(); 208 209 ECHO_DEBUGPRINTF( ( "CLayla24::InitHw()\n" ) ); 210 return Status; 211 212 } // ECHOSTATUS CLayla24::InitHw() 213 214 215 216 217 /**************************************************************************** 218 219 Informational methods 220 221 ****************************************************************************/ 222 223 //=========================================================================== 224 // 225 // Override GetCapabilities to enumerate unique capabilties for this card 226 // 227 //=========================================================================== 228 229 ECHOSTATUS CLayla24::GetCapabilities 230 ( 231 PECHOGALS_CAPS pCapabilities 232 ) 233 { 234 ECHOSTATUS Status; 235 WORD i; 236 237 Status = GetBaseCapabilities(pCapabilities); 238 239 if ( ECHOSTATUS_OK != Status ) 240 return Status; 241 242 // 243 // Add nominal level control to analog ins & outs 244 // 245 for (i = 0 ; i < GetFirstDigitalBusOut(); i++) 246 { 247 pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 248 } 249 250 for (i = 0 ; i < GetNumBussesIn(); i++) 251 { 252 pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 253 } 254 255 pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD | 256 ECHO_CLOCK_BIT_SPDIF | 257 ECHO_CLOCK_BIT_ADAT | 258 ECHO_CLOCK_BIT_MTC; 259 260 return Status; 261 262 } // ECHOSTATUS CLayla24::GetCapabilities 263 264 265 //=========================================================================== 266 // 267 // QueryAudioSampleRate is used to find out if this card can handle a 268 // given sample rate. 269 // 270 //=========================================================================== 271 272 ECHOSTATUS CLayla24::QueryAudioSampleRate 273 ( 274 DWORD dwSampleRate 275 ) 276 { 277 // 278 // Standard sample rates are allowed (like Mona & Layla24) 279 // 280 switch ( dwSampleRate ) 281 { 282 case 8000 : 283 case 11025 : 284 case 16000 : 285 case 22050 : 286 case 32000 : 287 case 44100 : 288 case 48000 : 289 goto qasr_ex; 290 291 case 88200 : 292 case 96000 : 293 294 // 295 // Double speed sample rates not allowed in ADAT mode 296 // 297 if ( DIGITAL_MODE_ADAT == GetDigitalMode() ) 298 { 299 ECHO_DEBUGPRINTF( 300 ("CLayla24::QueryAudioSampleRate() Sample rate must be < " 301 "50,000 Hz in ADAT mode\n") ); 302 return ECHOSTATUS_BAD_FORMAT; 303 } 304 goto qasr_ex; 305 } 306 307 // 308 // Any rate from 25000 to 50000 is allowed 309 // 310 if ( ( dwSampleRate >= 25000 ) && 311 ( dwSampleRate <= 50000 ) ) 312 goto qasr_ex; 313 314 // 315 // If not in ADAT mode, any rate from 50,000 to 100,000 is allowed 316 // 317 if ( DIGITAL_MODE_ADAT != GetDigitalMode() && 318 ( dwSampleRate >= 50000 ) && 319 ( dwSampleRate <= 100000 ) ) 320 goto qasr_ex; 321 322 ECHO_DEBUGPRINTF( 323 ("CLayla24::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) ); 324 return ECHOSTATUS_BAD_FORMAT; 325 326 qasr_ex: 327 ECHO_DEBUGPRINTF( ( "CLayla24::QueryAudioSampleRate() %ld Hz OK\n", 328 dwSampleRate ) ); 329 return ECHOSTATUS_OK; 330 } // ECHOSTATUS CLayla24::QueryAudioSampleRate 331 332 333 void CLayla24::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate) 334 { 335 dwMinRate = 8000; 336 dwMaxRate = 96000; 337 } 338 339 340 341 //=========================================================================== 342 // 343 // GetInputClockDetect returns a bitmask consisting of all the input 344 // clocks currently connected to the hardware; this changes as the user 345 // connects and disconnects clock inputs. 346 // 347 // You should use this information to determine which clocks the user is 348 // allowed to select. 349 // 350 // Layla24 supports S/PDIF, word, and ADAT input clocks. 351 // 352 //=========================================================================== 353 354 ECHOSTATUS CLayla24::GetInputClockDetect(DWORD &dwClockDetectBits) 355 { 356 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) 357 { 358 ECHO_DEBUGPRINTF( ("CLayla24::GetInputClockDetect: DSP Dead!\n") ); 359 return ECHOSTATUS_DSP_DEAD; 360 } 361 362 // 363 // Map the DSP clock detect bits to the generic driver clock detect bits 364 // 365 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); 366 367 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_MTC; 368 369 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF)) 370 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; 371 372 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT)) 373 dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT; 374 375 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD)) 376 dwClockDetectBits |= ECHO_CLOCK_BIT_WORD; 377 378 return ECHOSTATUS_OK; 379 380 } // GetInputClockDetect 381 382 383 // *** Layla24.cpp *** 384