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 53PVOID 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 76VOID 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 91CGina24::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 103CGina24::~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 123ECHOSTATUS 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 221ECHOSTATUS 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 264ECHOSTATUS 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 296void 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 316ECHOSTATUS 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