1 // **************************************************************************** 2 // 3 // CGina24.cpp 4 // 5 // Implementation file for the CGina24 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 "CGina24.h" 32 33 #define GINA24_ANALOG_OUTPUT_LATENCY 59 34 #define GINA24_ANALOG_INPUT_LATENCY 71 35 #define GINA24_DIGITAL_OUTPUT_LATENCY 32 36 #define GINA24_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 CGina24::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(("CGina::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 CGina24::operator new( size_t Size ) 74 75 76 VOID CGina24::operator delete( PVOID pVoid ) 77 { 78 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 79 { 80 ECHO_DEBUGPRINTF(("CGina24::operator delete memory free failed\n")); 81 } 82 } // VOID CGina24::operator delete( PVOID pVoid ) 83 84 85 //=========================================================================== 86 // 87 // Constructor and destructor 88 // 89 //=========================================================================== 90 91 CGina24::CGina24( PCOsSupport pOsSupport ) 92 : CEchoGals( pOsSupport ) 93 { 94 ECHO_DEBUGPRINTF( ( "CGina24::CGina24() is born!\n" ) ); 95 96 m_wAnalogOutputLatency = GINA24_ANALOG_OUTPUT_LATENCY; 97 m_wAnalogInputLatency = GINA24_ANALOG_INPUT_LATENCY; 98 m_wDigitalOutputLatency = GINA24_DIGITAL_OUTPUT_LATENCY; 99 m_wDigitalInputLatency = GINA24_DIGITAL_INPUT_LATENCY; 100 101 } 102 103 CGina24::~CGina24() 104 { 105 ECHO_DEBUGPRINTF( ( "CGina24::~CGina24() is toast!\n" ) ); 106 } 107 108 109 110 111 /**************************************************************************** 112 113 Setup and hardware initialization 114 115 ****************************************************************************/ 116 117 //=========================================================================== 118 // 119 // Every card has an InitHw method 120 // 121 //=========================================================================== 122 123 ECHOSTATUS CGina24::InitHw() 124 { 125 ECHOSTATUS Status; 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 ECHO_ASSERT(NULL == m_pDspCommObject ); 137 m_pDspCommObject = new CGina24DspCommObject( (PDWORD) m_pvSharedMemory, 138 m_pOsSupport ); 139 if (NULL == m_pDspCommObject) 140 { 141 ECHO_DEBUGPRINTF(("CGina24::InitHw - could not create DSP comm object\n")); 142 return ECHOSTATUS_NO_MEM; 143 } 144 145 ECHO_ASSERT(GetDspCommObject() ); 146 147 // 148 // Load the DSP and the ASIC on the PCI card 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 // Gina24 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 // Set defaults for +4/-10 173 // 174 WORD i; 175 for (i = 0; i < GetFirstDigitalBusOut(); i++ ) 176 { 177 Status = GetDspCommObject()-> 178 SetNominalLevel( i, FALSE ); // FALSE is +4 here 179 } 180 for ( i = 0; i < GetFirstDigitalBusIn(); i++ ) 181 { 182 Status = GetDspCommObject()-> 183 SetNominalLevel( GetNumBussesOut() + i, FALSE ); 184 } 185 186 // 187 // Set the digital mode to S/PDIF RCA 188 // 189 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA ); 190 191 // 192 // Set the S/PDIF output format to "professional" 193 // 194 SetProfessionalSpdif( TRUE ); 195 196 // 197 // Get default sample rate from DSP 198 // 199 m_dwSampleRate = GetDspCommObject()->GetSampleRate(); 200 201 ECHO_DEBUGPRINTF( ( "CGina24::InitHw()\n" ) ); 202 return Status; 203 204 } // ECHOSTATUS CGina24::InitHw() 205 206 207 208 209 /**************************************************************************** 210 211 Informational methods 212 213 ****************************************************************************/ 214 215 //=========================================================================== 216 // 217 // Override GetCapabilities to enumerate unique capabilties for Gina24 218 // 219 //=========================================================================== 220 221 ECHOSTATUS CGina24::GetCapabilities 222 ( 223 PECHOGALS_CAPS pCapabilities 224 ) 225 { 226 ECHOSTATUS Status; 227 228 Status = GetBaseCapabilities(pCapabilities); 229 230 // 231 // Add nominal level control to analog ins & outs 232 // 233 WORD i; 234 for (i = 0 ; i < GetFirstDigitalBusOut(); i++) 235 { 236 pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 237 } 238 239 for (i = 0 ; i < GetFirstDigitalBusIn(); i++) 240 { 241 pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 242 } 243 244 if ( ECHOSTATUS_OK != Status ) 245 return Status; 246 247 pCapabilities->dwInClockTypes |= 248 ECHO_CLOCK_BIT_SPDIF | 249 ECHO_CLOCK_BIT_ESYNC | 250 ECHO_CLOCK_BIT_ESYNC96 | 251 ECHO_CLOCK_BIT_ADAT; 252 253 return Status; 254 } // ECHOSTATUS CGina24::GetCapabilities 255 256 257 //=========================================================================== 258 // 259 // QueryAudioSampleRate is used to find out if this card can handle a 260 // given sample rate. 261 // 262 //=========================================================================== 263 264 ECHOSTATUS CGina24::QueryAudioSampleRate 265 ( 266 DWORD dwSampleRate 267 ) 268 { 269 if ( dwSampleRate != 8000 && 270 dwSampleRate != 11025 && 271 dwSampleRate != 16000 && 272 dwSampleRate != 22050 && 273 dwSampleRate != 32000 && 274 dwSampleRate != 44100 && 275 dwSampleRate != 48000 && 276 dwSampleRate != 88200 && 277 dwSampleRate != 96000 ) 278 { 279 ECHO_DEBUGPRINTF( 280 ("CGina24::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) ); 281 return ECHOSTATUS_BAD_FORMAT; 282 } 283 if ( dwSampleRate >= 88200 && DIGITAL_MODE_ADAT == GetDigitalMode() ) 284 { 285 ECHO_DEBUGPRINTF( 286 ("CGina24::QueryAudioSampleRate() Sample rate cannot be " 287 "set to 88,200 Hz or 96,000 Hz in ADAT mode\n") ); 288 return ECHOSTATUS_BAD_FORMAT; 289 } 290 291 ECHO_DEBUGPRINTF( ( "CGina24::QueryAudioSampleRate()\n" ) ); 292 return ECHOSTATUS_OK; 293 } // ECHOSTATUS CGina24::QueryAudioSampleRate 294 295 296 void CGina24::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate) 297 { 298 dwMinRate = 8000; 299 dwMaxRate = 96000; 300 } 301 302 303 //=========================================================================== 304 // 305 // GetInputClockDetect returns a bitmask consisting of all the input 306 // clocks currently connected to the hardware; this changes as the user 307 // connects and disconnects clock inputs. 308 // 309 // You should use this information to determine which clocks the user is 310 // allowed to select. 311 // 312 // Gina24 supports S/PDIF, Esync, and ADAT input clocks. 313 // 314 //=========================================================================== 315 316 ECHOSTATUS CGina24::GetInputClockDetect(DWORD &dwClockDetectBits) 317 { 318 //ECHO_DEBUGPRINTF(("CGina24::GetInputClockDetect\n")); 319 320 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) 321 { 322 ECHO_DEBUGPRINTF( ("CGina24::GetInputClockDetect: DSP Dead!\n") ); 323 return ECHOSTATUS_DSP_DEAD; 324 } 325 326 // 327 // Map the DSP clock detect bits to the generic driver clock detect bits 328 // 329 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); 330 331 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL; 332 333 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF)) 334 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; 335 336 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT)) 337 dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT; 338 339 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ESYNC)) 340 dwClockDetectBits |= ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96; 341 342 return ECHOSTATUS_OK; 343 344 } // GetInputClockDetect 345 346 347 // *** CGina24.cpp *** 348