1// **************************************************************************** 2// 3// CMia.cpp 4// 5// Implementation file for the CMia 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 "CMia.h" 32 33#define MIA_ANALOG_OUTPUT_LATENCY 63 34#define MIA_ANALOG_INPUT_LATENCY 62 35 36 37 38/**************************************************************************** 39 40 Construction and destruction 41 42 ****************************************************************************/ 43 44//=========================================================================== 45// 46// Overload new & delete so memory for this object is allocated 47// from non-paged memory. 48// 49//=========================================================================== 50 51PVOID CMia::operator new( size_t Size ) 52{ 53 PVOID pMemory; 54 ECHOSTATUS Status; 55 56 Status = OsAllocateNonPaged(Size,&pMemory); 57 58 if ( (ECHOSTATUS_OK != Status) || (NULL == pMemory )) 59 { 60 ECHO_DEBUGPRINTF(("CMia::operator new - memory allocation failed\n")); 61 62 pMemory = NULL; 63 } 64 else 65 { 66 memset( pMemory, 0, Size ); 67 } 68 69 return pMemory; 70 71} // PVOID CMia::operator new( size_t Size ) 72 73 74VOID CMia::operator delete( PVOID pVoid ) 75{ 76 if ( ECHOSTATUS_OK != OsFreeNonPaged( pVoid ) ) 77 { 78 ECHO_DEBUGPRINTF(("CMia::operator delete memory free failed\n")); 79 } 80} // VOID CMia::operator delete( PVOID pVoid ) 81 82 83//=========================================================================== 84// 85// Constructor and destructor 86// 87//=========================================================================== 88 89CMia::CMia( PCOsSupport pOsSupport ) 90 : CEchoGalsVmixer( pOsSupport ) 91{ 92 ECHO_DEBUGPRINTF( ( "CMia::CMia() is born!\n" ) ); 93 94 // 95 // Mia's virtual outputs make things tricky, since a pipe can 96 // go to either bus. 97 // 98 m_wAnalogOutputLatency = MIA_ANALOG_OUTPUT_LATENCY; 99 m_wAnalogInputLatency = MIA_ANALOG_INPUT_LATENCY; 100 101} 102 103CMia::~CMia() 104{ 105 ECHO_DEBUGPRINTF( ( "CMia::~CMia() 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 CMia::InitHw() 124{ 125 ECHOSTATUS Status; 126 WORD i; 127 128 // 129 // Call the base method 130 // 131 if ( ECHOSTATUS_OK != ( Status = CEchoGals::InitHw() ) ) 132 return Status; 133 134 // 135 // Create the DSP comm object 136 // 137 ECHO_ASSERT(NULL == m_pDspCommObject ); 138 m_pDspCommObject = new CMiaDspCommObject( (PDWORD) m_pvSharedMemory, 139 m_pOsSupport ); 140 if (NULL == m_pDspCommObject) 141 { 142 ECHO_DEBUGPRINTF(("CMia::InitHw - could not create DSP comm object\n")); 143 return ECHOSTATUS_NO_MEM; 144 } 145 146 // 147 // Load the DSP 148 // 149 GetDspCommObject()->LoadFirmware(); 150 if ( GetDspCommObject()->IsBoardBad() ) 151 return ECHOSTATUS_DSP_DEAD; 152 153 // 154 // Clear the "bad board" flag; set the flags to indicate that 155 // Mia can handle super-interleave. 156 // 157 m_wFlags &= ~ECHOGALS_FLAG_BADBOARD; 158 m_wFlags |= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK; 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 defaults for +4/-10 170 // 171 for (i = 0; i < GetFirstDigitalBusOut(); i++ ) 172 { 173 GetDspCommObject()-> 174 SetNominalLevel( i, FALSE ); // FALSE is +4 here 175 } 176 for ( i = 0; i < GetFirstDigitalBusIn(); i++ ) 177 { 178 GetDspCommObject()-> 179 SetNominalLevel( GetNumBussesOut() + i, FALSE ); 180 } 181 182 // 183 // Set the digital mode to S/PDIF RCA 184 // 185 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA ); 186 187 // 188 // Get default sample rate from DSP 189 // 190 m_dwSampleRate = GetDspCommObject()->GetSampleRate(); 191 192 // 193 // Is this a Mia MIDI card? 194 // 195 if (MIA_MIDI_REV == m_pOsSupport->GetCardRev()) 196 { 197 Status = m_MidiIn.Init( this ); 198 } 199 200 201 ECHO_DEBUGPRINTF( ( "CMia::InitHw()\n" ) ); 202 return Status; 203 204} // ECHOSTATUS CMia::InitHw() 205 206 207 208 209/**************************************************************************** 210 211 Informational methods 212 213 ****************************************************************************/ 214 215//=========================================================================== 216// 217// Override GetCapabilities to enumerate unique capabilties for this card 218// 219//=========================================================================== 220 221ECHOSTATUS CMia::GetCapabilities 222( 223 PECHOGALS_CAPS pCapabilities 224) 225{ 226 ECHOSTATUS Status; 227 WORD i; 228 229 Status = GetBaseCapabilities(pCapabilities); 230 if ( ECHOSTATUS_OK != Status ) 231 return Status; 232 233 // 234 // Add nominal level control to analog ins & outs 235 // 236 for (i = 0 ; i < GetFirstDigitalBusOut(); i++) 237 { 238 pCapabilities->dwBusOutCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 239 } 240 241 for (i = 0 ; i < GetFirstDigitalBusIn(); i++) 242 { 243 pCapabilities->dwBusInCaps[i] |= ECHOCAPS_NOMINAL_LEVEL; 244 } 245 246 pCapabilities->dwInClockTypes |= ECHO_CLOCK_BIT_SPDIF; 247 pCapabilities->dwOutClockTypes = 0; 248 249 return Status; 250 251} // ECHOSTATUS CMia::GetCapabilities 252 253 254//=========================================================================== 255// 256// QueryAudioSampleRate is used to find out if this card can handle a 257// given sample rate. 258// 259//=========================================================================== 260 261ECHOSTATUS CMia::QueryAudioSampleRate 262( 263 DWORD dwSampleRate 264) 265{ 266 if ( dwSampleRate != 32000 && 267 dwSampleRate != 44100 && 268 dwSampleRate != 48000 && 269 dwSampleRate != 88200 && 270 dwSampleRate != 96000 ) 271 { 272 ECHO_DEBUGPRINTF( 273 ("CMia::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate) ); 274 return ECHOSTATUS_BAD_FORMAT; 275 } 276 277 ECHO_DEBUGPRINTF( ( "CMia::QueryAudioSampleRate()\n" ) ); 278 return ECHOSTATUS_OK; 279 280} // ECHOSTATUS CMia::QueryAudioSampleRate 281 282 283void CMia::QuerySampleRateRange(DWORD &dwMinRate,DWORD &dwMaxRate) 284{ 285 dwMinRate = 32000; 286 dwMaxRate = 96000; 287} 288 289 290 291//=========================================================================== 292// 293// GetInputClockDetect returns a bitmask consisting of all the input 294// clocks currently connected to the hardware; this changes as the user 295// connects and disconnects clock inputs. 296// 297// You should use this information to determine which clocks the user is 298// allowed to select. 299// 300// Mia supports S/PDIF input clock. 301// 302//=========================================================================== 303 304ECHOSTATUS CMia::GetInputClockDetect(DWORD &dwClockDetectBits) 305{ 306 //ECHO_DEBUGPRINTF(("CMia::GetInputClockDetect\n")); 307 308 if ( NULL == GetDspCommObject() || GetDspCommObject()->IsBoardBad() ) 309 { 310 //ECHO_DEBUGPRINTF( ("CMia::GetInputClockDetect: DSP Dead!\n") ); 311 return ECHOSTATUS_DSP_DEAD; 312 } 313 314 // 315 // Map the DSP clock detect bits to the generic driver clock detect bits 316 // 317 DWORD dwClocksFromDsp = GetDspCommObject()->GetInputClockDetect(); 318 319 dwClockDetectBits = ECHO_CLOCK_BIT_INTERNAL; 320 321 if (0 != (dwClocksFromDsp & GLDM_CLOCK_DETECT_BIT_SPDIF)) 322 dwClockDetectBits |= ECHO_CLOCK_BIT_SPDIF; 323 324 return ECHOSTATUS_OK; 325 326} // GetInputClockDetect 327 328 329 330// *** Mia.cpp *** 331