1 // **************************************************************************** 2 // 3 // CGina24DspCommObject.cpp 4 // 5 // Implementation file for Gina24 DSP interface class. 6 // 7 // ---------------------------------------------------------------------------- 8 // 9 // This file is part of Echo Digital Audio's generic driver library. 10 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005 11 // All rights reserved 12 // www.echoaudio.com 13 // 14 // This library is free software; you can redistribute it and/or 15 // modify it under the terms of the GNU Lesser General Public 16 // License as published by the Free Software Foundation; either 17 // version 2.1 of the License, or (at your option) any later version. 18 // 19 // This library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 // Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public 25 // License along with this library; if not, write to the Free Software 26 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 // 28 // **************************************************************************** 29 30 #include "CEchoGals.h" 31 #include "CGina24DspCommObject.h" 32 33 #include "Gina24DSP.c" 34 #include "Gina24_361DSP.c" 35 36 #include "Gina24ASIC.c" 37 #include "Gina24ASIC_361.c" 38 39 40 /**************************************************************************** 41 42 Construction and destruction 43 44 ****************************************************************************/ 45 46 //=========================================================================== 47 // 48 // Constructor 49 // 50 //=========================================================================== 51 52 CGina24DspCommObject::CGina24DspCommObject 53 ( 54 PDWORD pdwRegBase, // Virtual ptr to DSP registers 55 PCOsSupport pOsSupport 56 ) : CGMLDspCommObject( pdwRegBase, pOsSupport ) 57 { 58 strcpy( m_szCardName, "Gina24" ); 59 m_pdwDspRegBase = pdwRegBase; // Virtual addr DSP's register base 60 61 m_wNumPipesOut = 16; 62 m_wNumPipesIn = 10; 63 m_wNumBussesOut = 16; 64 m_wNumBussesIn = 10; 65 m_wFirstDigitalBusOut = 8; 66 m_wFirstDigitalBusIn = 2; 67 68 m_fHasVmixer = FALSE; 69 70 m_wNumMidiOut = 0; // # MIDI out channels 71 m_wNumMidiIn = 0; // # MIDI in channels 72 m_pDspCommPage->dwSampleRate = SWAP( (DWORD) 44100 ); 73 // Need this in cse we start with ESYNC 74 m_bHasASIC = TRUE; 75 76 // 77 // Gina24 comes in both '301 and '361 flavors; pick the correct one. 78 // 79 if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() ) 80 m_pwDspCodeToLoad = pwGina24_361DSP; 81 else 82 m_pwDspCodeToLoad = pwGina24DSP; 83 84 m_byDigitalMode = DIGITAL_MODE_SPDIF_RCA; 85 m_bProfessionalSpdif = FALSE; 86 } // CGina24DspCommObject::CGina24DspCommObject( DWORD dwPhysRegBase ) 87 88 89 //=========================================================================== 90 // 91 // Destructor 92 // 93 //=========================================================================== 94 95 CGina24DspCommObject::~CGina24DspCommObject() 96 { 97 ECHO_DEBUGPRINTF(("CGina24DspCommObject::~CGina24DspCommObject - " 98 "hasta la vista!\n")); 99 } // CGina24DspCommObject::~CGina24DspCommObject() 100 101 102 103 104 /**************************************************************************** 105 106 Hardware setup and config 107 108 ****************************************************************************/ 109 110 //=========================================================================== 111 // 112 // Gina24 has an ASIC on the PCI card which must be loaded for anything 113 // interesting to happen. 114 // 115 //=========================================================================== 116 117 BOOL CGina24DspCommObject::LoadASIC() 118 { 119 DWORD dwControlReg, dwSize; 120 PBYTE pbAsic; 121 122 if ( m_bASICLoaded ) 123 return TRUE; 124 125 // 126 // Give the DSP a few milliseconds to settle down 127 // 128 m_pOsSupport->OsSnooze( 10000 ); 129 130 // 131 // Pick the correct ASIC for '301 or '361 Gina24 132 // 133 if ( DEVICE_ID_56361 == m_pOsSupport->GetDeviceId() ) 134 { 135 pbAsic = pbGina24ASIC_361; 136 dwSize = sizeof( pbGina24ASIC_361 ); 137 } 138 else 139 { 140 pbAsic = pbGina24ASIC; 141 dwSize = sizeof( pbGina24ASIC ); 142 } 143 if ( !CDspCommObject::LoadASIC( DSP_FNC_LOAD_GINA24_ASIC, 144 pbAsic, 145 dwSize ) ) 146 return FALSE; 147 148 m_pbyAsic = pbAsic; 149 150 // 151 // Now give the new ASIC a little time to set up 152 // 153 m_pOsSupport->OsSnooze( 10000 ); 154 155 // 156 // See if it worked 157 // 158 CheckAsicStatus(); 159 160 // 161 // Set up the control register if the load succeeded - 162 // 163 // 48 kHz, internal clock, S/PDIF RCA mode 164 // 165 if ( m_bASICLoaded ) 166 { 167 dwControlReg = GML_CONVERTER_ENABLE | GML_48KHZ; 168 WriteControlReg( dwControlReg, TRUE ); 169 } 170 171 return m_bASICLoaded; 172 173 } // BOOL CGina24DspCommObject::LoadASIC() 174 175 176 //=========================================================================== 177 // 178 // Set the input clock to internal, S/PDIF, ADAT 179 // 180 //=========================================================================== 181 182 ECHOSTATUS CGina24DspCommObject::SetInputClock(WORD wClock) 183 { 184 BOOL bSetRate; 185 BOOL bWriteControlReg; 186 DWORD dwControlReg; 187 188 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetInputClock:\n") ); 189 190 dwControlReg = GetControlRegister(); 191 192 // 193 // Mask off the clock select bits 194 // 195 dwControlReg &= GML_CLOCK_CLEAR_MASK; 196 197 bSetRate = FALSE; 198 bWriteControlReg = TRUE; 199 switch ( wClock ) 200 { 201 case ECHO_CLOCK_INTERNAL : 202 { 203 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to INTERNAL\n" ) ); 204 205 bSetRate = TRUE; 206 bWriteControlReg = FALSE; 207 break; 208 } // ECHO_CLOCK_INTERNAL 209 210 case ECHO_CLOCK_SPDIF : 211 { 212 if ( DIGITAL_MODE_ADAT == GetDigitalMode() ) 213 { 214 return ECHOSTATUS_CLOCK_NOT_AVAILABLE; 215 } 216 217 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to SPDIF\n" ) ); 218 219 dwControlReg |= GML_SPDIF_CLOCK; 220 221 if ( GML_CLOCK_DETECT_BIT_SPDIF96 & GetInputClockDetect() ) 222 { 223 dwControlReg |= GML_DOUBLE_SPEED_MODE; 224 } 225 else 226 { 227 dwControlReg &= ~GML_DOUBLE_SPEED_MODE; 228 } 229 break; 230 } // ECHO_CLOCK_SPDIF 231 232 case ECHO_CLOCK_ADAT : 233 { 234 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ADAT\n" ) ); 235 236 if ( DIGITAL_MODE_ADAT != GetDigitalMode() ) 237 { 238 return ECHOSTATUS_CLOCK_NOT_AVAILABLE; 239 } 240 241 dwControlReg |= GML_ADAT_CLOCK; 242 dwControlReg &= ~GML_DOUBLE_SPEED_MODE; 243 break; 244 } // ECHO_CLOCK_ADAT 245 246 case ECHO_CLOCK_ESYNC : 247 { 248 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC\n" ) ); 249 250 dwControlReg |= GML_ESYNC_CLOCK; 251 dwControlReg &= ~GML_DOUBLE_SPEED_MODE; 252 break; 253 } // ECHO_CLOCK_ESYNC 254 255 case ECHO_CLOCK_ESYNC96 : 256 { 257 ECHO_DEBUGPRINTF( ( "\tSet Gina24 clock to ESYNC96\n" ) ); 258 259 dwControlReg |= GML_ESYNC_CLOCK | GML_DOUBLE_SPEED_MODE; 260 break; 261 } // ECHO_CLOCK_ESYNC96 262 263 default : 264 ECHO_DEBUGPRINTF(("Input clock 0x%x not supported for Gina24\n",wClock)); 265 ECHO_DEBUGBREAK(); 266 return ECHOSTATUS_CLOCK_NOT_SUPPORTED; 267 } // switch (wInputClock) 268 269 270 // 271 // Winner! Save the new input clock. 272 // 273 m_wInputClock = wClock; 274 275 // 276 // Write the control reg if that's called for 277 // 278 if ( bWriteControlReg ) 279 { 280 WriteControlReg( dwControlReg, TRUE ); 281 } 282 283 // Set Gina24 sample rate to something sane if word or superword is 284 // being turned off 285 if ( bSetRate ) 286 { 287 SetSampleRate( GetSampleRate() ); 288 } 289 return ECHOSTATUS_OK; 290 291 } // ECHOSTATUS CGina24DspCommObject::SetInputClock 292 293 294 //=========================================================================== 295 // 296 // SetSampleRate 297 // 298 // Set the audio sample rate for Gina24 299 // 300 //=========================================================================== 301 302 DWORD CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate ) 303 { 304 DWORD dwControlReg, dwNewClock; 305 306 // 307 // Only set the clock for internal mode. If the clock is not set to 308 // internal, try and re-set the input clock; this more transparently 309 // handles switching between single and double-speed mode 310 // 311 if ( GetInputClock() != ECHO_CLOCK_INTERNAL ) 312 { 313 ECHO_DEBUGPRINTF( ( "CGina24DspCommObject::SetSampleRate: Cannot set sample rate - " 314 "clock not set to CLK_CLOCKININTERNAL\n" ) ); 315 316 // 317 // Save the rate anyhow 318 // 319 m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate ); 320 321 // 322 // Set the input clock to the current value 323 // 324 SetInputClock( m_wInputClock ); 325 326 return GetSampleRate(); 327 } 328 329 // 330 // Set the sample rate 331 // 332 dwNewClock = 0; 333 334 dwControlReg = GetControlRegister(); 335 dwControlReg &= GML_CLOCK_CLEAR_MASK; 336 dwControlReg &= GML_SPDIF_RATE_CLEAR_MASK; 337 338 switch ( dwNewSampleRate ) 339 { 340 case 96000 : 341 dwNewClock = GML_96KHZ; 342 break; 343 344 case 88200 : 345 dwNewClock = GML_88KHZ; 346 break; 347 348 case 48000 : 349 dwNewClock = GML_48KHZ | GML_SPDIF_SAMPLE_RATE1; 350 break; 351 352 case 44100 : 353 dwNewClock = GML_44KHZ; 354 // 355 // Professional mode 356 // 357 if ( dwControlReg & GML_SPDIF_PRO_MODE ) 358 { 359 dwNewClock |= GML_SPDIF_SAMPLE_RATE0; 360 } 361 break; 362 363 case 32000 : 364 dwNewClock = GML_32KHZ | 365 GML_SPDIF_SAMPLE_RATE0 | 366 GML_SPDIF_SAMPLE_RATE1; 367 break; 368 369 case 22050 : 370 dwNewClock = GML_22KHZ; 371 break; 372 373 case 16000 : 374 dwNewClock = GML_16KHZ; 375 break; 376 377 case 11025 : 378 dwNewClock = GML_11KHZ; 379 break; 380 381 case 8000 : 382 dwNewClock = GML_8KHZ; 383 break; 384 385 default : 386 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld " 387 "invalid!\n", dwNewSampleRate) ); 388 ECHO_DEBUGBREAK(); 389 return( GetSampleRate() ); 390 } 391 392 dwControlReg |= dwNewClock; 393 394 // 395 // Send the new value to the DSP 396 // 397 if ( ECHOSTATUS_OK == WriteControlReg( dwControlReg ) ) 398 { 399 m_pDspCommPage->dwSampleRate = SWAP( dwNewSampleRate ); 400 401 ECHO_DEBUGPRINTF( ("CGina24DspCommObject::SetSampleRate: %ld " 402 "clock %ld\n", dwNewSampleRate, dwNewClock) ); 403 } 404 405 return GetSampleRate(); 406 407 } // DWORD CGina24DspCommObject::SetSampleRate( DWORD dwNewSampleRate ) 408 409 410 411 // **** CGina24DspCommObject.cpp **** 412