1// **************************************************************************** 2// 3// CMona.cpp 4// 5// Implementation file for the CMona 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 "CMona.h" 32 33#define MONA_ANALOG_OUTPUT_LATENCY 59 34#define MONA_ANALOG_INPUT_LATENCY 71 35#define MONA_DIGITAL_OUTPUT_LATENCY 32 36#define MONA_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 CMona::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(("CMona::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 CMona::operator new( size_t Size ) 74 75 76VOID CMona::operator delete( PVOID pVoid ) 77{ 78 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 79 { 80 ECHO_DEBUGPRINTF(("CMona::operator delete memory free failed\n")); 81 } 82} // VOID CMona::operator delete( PVOID pVoid ) 83 84 85//=========================================================================== 86// 87// Constructor and destructor 88// 89//=========================================================================== 90 91CMona::CMona( PCOsSupport pOsSupport ) 92 : CEchoGals( pOsSupport ) 93{ 94 ECHO_DEBUGPRINTF( ( "CMona::CMona() is born!\n" ) ); 95 96 m_wAnalogOutputLatency = MONA_ANALOG_OUTPUT_LATENCY; 97 m_wAnalogInputLatency = MONA_ANALOG_INPUT_LATENCY; 98 m_wDigitalOutputLatency = MONA_DIGITAL_OUTPUT_LATENCY; 99 m_wDigitalInputLatency = MONA_DIGITAL_INPUT_LATENCY; 100} 101 102CMona::~CMona() 103{ 104 ECHO_DEBUGPRINTF( ( "CMona::~CMona() is toast!\n" ) ); 105} 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 122ECHOSTATUS CMona::InitHw() 123{ 124 ECHOSTATUS Status; 125 126 // 127 // Call the base method 128 // 129 if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) ) 130 return Status; 131 132 // 133 // Create the DSP comm object 134 // 135 ECHO_ASSERT(NULL == m_pDspCommObject ); 136 m_pDspCommObject = new CMonaDspCommObject( (PDWORD) m_pvSharedMemory, 137 m_pOsSupport ); 138 if (NULL == m_pDspCommObject) 139 { 140 ECHO_DEBUGPRINTF(("CMona::InitHw - could not create DSP comm object\n")); 141 return ECHOSTATUS_NO_MEM; 142 } 143 144 // 145 // Load the DSP, the PCI card ASIC, and the external box ASIC 146 // 147 GetDspCommObject()->LoadFirmware(); 148 if ( GetDspCommObject()->IsBoardBad() ) 149 return ECHOSTATUS_DSP_DEAD; 150 151 // 152 // Clear the "bad board" flag; set the flags to indicate that 153 // Mona can handle super-interleave and supports the digital 154 // input auto-mute. 155 // 156 m_wFlags &= ~ECHOGALS_FLAG_BADBOARD; 157 m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK | 158 ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE; 159 160 // 161 // Must call this here after DSP is init to 162 // init gains and mutes 163 // 164 Status = InitLineLevels(); 165 if ( ECHOSTATUS_OK != Status ) 166 return Status; 167 168 // 169 // Set the digital mode to S/PDIF RCA 170 // 171 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA ); 172 173 // 174 // Set the S/PDIF output format to "professional" 175 // 176 SetProfessionalSpdif( TRUE ); 177 178 // 179 // Get default sample rate from DSP 180 // 181 m_dwSampleRate = GetDspCommObject()->GetSampleRate(); 182 183 ECHO_DEBUGPRINTF( ( "CMona::InitHw()\n" ) ); 184 return Status; 185 186} // ECHOSTATUS CMona::InitHw() 187 188 189 190 191/**************************************************************************** 192 193 Informational methods 194 195 ****************************************************************************/ 196 197//=========================================================================== 198// 199// Override GetCapabilities to enumerate unique capabilties for this card 200// 201//=========================================================================== 202 203ECHOSTATUS CMona::GetCapabilities 204( 205 PECHOGALS_CAPS pCapabilities 206) 207{ 208 ECHOSTATUS Status; 209 210 Status = GetBaseCapabilities(pCapabilities); 211 if ( ECHOSTATUS_OK != Status ) 212 return Status; 213 214 pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_WORD | 215 ECHO_CLOCK_BIT_SPDIF | 216 ECHO_CLOCK_BIT_ADAT; 217 218 return Status; 219 220} // ECHOSTATUS CMona::GetCapabilities 221 222 223//=========================================================================== 224// 225// QueryAudioSampleRate is used to find out if this card can handle a 226// given sample rate. 227// 228//=========================================================================== 229 230ECHOSTATUS CMona::QueryAudioSampleRate 231( 232 DWORD dwSampleRate 233) 234{ 235 if ( dwSampleRate != 8000 && 236 dwSampleRate != 11025 && 237 dwSampleRate != 16000 && 238 dwSampleRate != 22050 && 239 dwSampleRate != 32000 && 240 dwSampleRate != 44100 && 241 dwSampleRate != 48000 && 242 dwSampleRate != 88200 && 243 dwSampleRate != 96000 ) 244 { 245 ECHO_DEBUGPRINTF( 246 ("CMona::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) ); 247 return ECHOSTATUS_BAD_FORMAT; 248 } 249 if ( dwSampleRate >= 88200 && DIGITAL_MODE_ADAT == GetDigitalMode() ) 250 { 251 ECHO_DEBUGPRINTF( 252 ("CMona::QueryAudioSampleRate() Sample rate cannot be " 253 "set to 88,200 Hz or 96,000 Hz in ADAT mode\n") ); 254 return ECHOSTATUS_BAD_FORMAT; 255 } 256 257 ECHO_DEBUGPRINTF( ( "CMona::QueryAudioSampleRate()\n" ) ); 258 return ECHOSTATUS_OK; 259} // ECHOSTATUS CMona::QueryAudioSampleRate 260 261 262void CMona::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate) 263{ 264 dwMinRate = 8000; 265 dwMaxRate = 96000; 266} 267 268 269//=========================================================================== 270// 271// GetInputClockDetect returns a bitmask consisting of all the input 272// clocks currently connected to the hardware; this changes as the user 273// connects and disconnects clock inputs. 274// 275// You should use this information to determine which clocks the user is 276// allowed to select. 277// 278// Mona supports S/PDIF, word, and ADAT input clocks. 279// 280//=========================================================================== 281 282ECHOSTATUS CMona::GetInputClockDetect(DWORD &dwClockDetectBits) 283{ 284 //ECHO_DEBUGPRINTF(("CMona::GetInputClockDetect\n")); 285 286 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) 287 { 288 ECHO_DEBUGPRINTF( ("CMona::GetInputClockDetect: DSP Dead!\n") ); 289 return ECHOSTATUS_DSP_DEAD; 290 } 291 292 // 293 // Map the DSP clock detect bits to the generic driver clock detect bits 294 // 295 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); 296 297 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL; 298 299 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF)) 300 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; 301 302 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT)) 303 dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT; 304 305 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD)) 306 dwClockDetectBits |= ECHO_CLOCK_BIT_WORD; 307 308 return ECHOSTATUS_OK; 309 310} // GetInputClockDetect 311 312 313// *** CMona.cpp *** 314