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 53 PVOID 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 76 VOID 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 91 CMona::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 102 CMona::~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 122 ECHOSTATUS 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 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 203 ECHOSTATUS 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 230 ECHOSTATUS 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 262 //=========================================================================== 263 // 264 // GetInputClockDetect returns a bitmask consisting of all the input 265 // clocks currently connected to the hardware; this changes as the user 266 // connects and disconnects clock inputs. 267 // 268 // You should use this information to determine which clocks the user is 269 // allowed to select. 270 // 271 // Mona supports S/PDIF, word, and ADAT input clocks. 272 // 273 //=========================================================================== 274 275 ECHOSTATUS CMona::GetInputClockDetect(DWORD &dwClockDetectBits) 276 { 277 //ECHO_DEBUGPRINTF(("CMona::GetInputClockDetect\n")); 278 279 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) 280 { 281 ECHO_DEBUGPRINTF( ("CMona::GetInputClockDetect: DSP Dead!\n") ); 282 return ECHOSTATUS_DSP_DEAD; 283 } 284 285 // 286 // Map the DSP clock detect bits to the generic driver clock detect bits 287 // 288 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); 289 290 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL; 291 292 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_SPDIF)) 293 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; 294 295 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_ADAT)) 296 dwClockDetectBits |= ECHO_CLOCK_BIT_ADAT; 297 298 if (0 != (dwClocksFromDsp & GML_CLOCK_DETECT_BIT_WORD)) 299 dwClockDetectBits |= ECHO_CLOCK_BIT_WORD; 300 301 return ECHOSTATUS_OK; 302 303 } // GetInputClockDetect 304 305 306 // *** CMona.cpp *** 307