1 // ****************************************************************************
5 // Implementation file for the CMia driver class.
6 // Set editor tabs to 3 for your viewing pleasure.
8 // ----------------------------------------------------------------------------
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
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.
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.
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
29 // ****************************************************************************
33 #define MIA_ANALOG_OUTPUT_LATENCY 63
34 #define MIA_ANALOG_INPUT_LATENCY 62
38 /****************************************************************************
40 Construction and destruction
42 ****************************************************************************/
44 //===========================================================================
46 // Overload new & delete so memory for this object is allocated
47 // from non-paged memory.
49 //===========================================================================
51 PVOID
CMia::operator new( size_t Size
)
56 Status
= OsAllocateNonPaged(Size
,&pMemory
);
58 if ( (ECHOSTATUS_OK
!= Status
) || (NULL
== pMemory
))
60 ECHO_DEBUGPRINTF(("CMia::operator new - memory allocation failed\n"));
66 memset( pMemory
, 0, Size
);
71 } // PVOID CMia::operator new( size_t Size )
74 VOID
CMia::operator delete( PVOID pVoid
)
76 if ( ECHOSTATUS_OK
!= OsFreeNonPaged( pVoid
) )
78 ECHO_DEBUGPRINTF(("CMia::operator delete memory free failed\n"));
80 } // VOID CMia::operator delete( PVOID pVoid )
83 //===========================================================================
85 // Constructor and destructor
87 //===========================================================================
89 CMia::CMia( PCOsSupport pOsSupport
)
90 : CEchoGalsVmixer( pOsSupport
)
92 ECHO_DEBUGPRINTF( ( "CMia::CMia() is born!\n" ) );
95 // Mia's virtual outputs make things tricky, since a pipe can
98 m_wAnalogOutputLatency
= MIA_ANALOG_OUTPUT_LATENCY
;
99 m_wAnalogInputLatency
= MIA_ANALOG_INPUT_LATENCY
;
105 ECHO_DEBUGPRINTF( ( "CMia::~CMia() is toast!\n" ) );
111 /****************************************************************************
113 Setup and hardware initialization
115 ****************************************************************************/
117 //===========================================================================
119 // Every card has an InitHw method
121 //===========================================================================
123 ECHOSTATUS
CMia::InitHw()
129 // Call the base method
131 if ( ECHOSTATUS_OK
!= ( Status
= CEchoGals::InitHw() ) )
135 // Create the DSP comm object
137 ECHO_ASSERT(NULL
== m_pDspCommObject
);
138 m_pDspCommObject
= new CMiaDspCommObject( (PDWORD
) m_pvSharedMemory
,
140 if (NULL
== m_pDspCommObject
)
142 ECHO_DEBUGPRINTF(("CMia::InitHw - could not create DSP comm object\n"));
143 return ECHOSTATUS_NO_MEM
;
149 GetDspCommObject()->LoadFirmware();
150 if ( GetDspCommObject()->IsBoardBad() )
151 return ECHOSTATUS_DSP_DEAD
;
154 // Clear the "bad board" flag; set the flags to indicate that
155 // Mia can handle super-interleave.
157 m_wFlags
&= ~ECHOGALS_FLAG_BADBOARD
;
158 m_wFlags
|= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK
;
161 // Must call this here after DSP is init to
162 // init gains and mutes
164 Status
= InitLineLevels();
165 if ( ECHOSTATUS_OK
!= Status
)
169 // Set defaults for +4/-10
171 for (i
= 0; i
< GetFirstDigitalBusOut(); i
++ )
174 SetNominalLevel( i
, FALSE
); // FALSE is +4 here
176 for ( i
= 0; i
< GetFirstDigitalBusIn(); i
++ )
179 SetNominalLevel( GetNumBussesOut() + i
, FALSE
);
183 // Set the digital mode to S/PDIF RCA
185 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA
);
188 // Get default sample rate from DSP
190 m_dwSampleRate
= GetDspCommObject()->GetSampleRate();
193 // Is this a Mia MIDI card?
195 if (MIA_MIDI_REV
== m_pOsSupport
->GetCardRev())
197 Status
= m_MidiIn
.Init( this );
201 ECHO_DEBUGPRINTF( ( "CMia::InitHw()\n" ) );
204 } // ECHOSTATUS CMia::InitHw()
209 /****************************************************************************
211 Informational methods
213 ****************************************************************************/
215 //===========================================================================
217 // Override GetCapabilities to enumerate unique capabilties for this card
219 //===========================================================================
221 ECHOSTATUS
CMia::GetCapabilities
223 PECHOGALS_CAPS pCapabilities
229 Status
= GetBaseCapabilities(pCapabilities
);
230 if ( ECHOSTATUS_OK
!= Status
)
234 // Add nominal level control to analog ins & outs
236 for (i
= 0 ; i
< GetFirstDigitalBusOut(); i
++)
238 pCapabilities
->dwBusOutCaps
[i
] |= ECHOCAPS_NOMINAL_LEVEL
;
241 for (i
= 0 ; i
< GetFirstDigitalBusIn(); i
++)
243 pCapabilities
->dwBusInCaps
[i
] |= ECHOCAPS_NOMINAL_LEVEL
;
246 pCapabilities
->dwInClockTypes
|= ECHO_CLOCK_BIT_SPDIF
;
247 pCapabilities
->dwOutClockTypes
= 0;
251 } // ECHOSTATUS CMia::GetCapabilities
254 //===========================================================================
256 // QueryAudioSampleRate is used to find out if this card can handle a
257 // given sample rate.
259 //===========================================================================
261 ECHOSTATUS
CMia::QueryAudioSampleRate
266 if ( dwSampleRate
!= 32000 &&
267 dwSampleRate
!= 44100 &&
268 dwSampleRate
!= 48000 &&
269 dwSampleRate
!= 88200 &&
270 dwSampleRate
!= 96000 )
273 ("CMia::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate
) );
274 return ECHOSTATUS_BAD_FORMAT
;
277 ECHO_DEBUGPRINTF( ( "CMia::QueryAudioSampleRate()\n" ) );
278 return ECHOSTATUS_OK
;
280 } // ECHOSTATUS CMia::QueryAudioSampleRate
283 void CMia::QuerySampleRateRange(DWORD
&dwMinRate
,DWORD
&dwMaxRate
)
291 //===========================================================================
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.
297 // You should use this information to determine which clocks the user is
298 // allowed to select.
300 // Mia supports S/PDIF input clock.
302 //===========================================================================
304 ECHOSTATUS
CMia::GetInputClockDetect(DWORD
&dwClockDetectBits
)
306 //ECHO_DEBUGPRINTF(("CMia::GetInputClockDetect\n"));
308 if ( NULL
== GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
310 //ECHO_DEBUGPRINTF( ("CMia::GetInputClockDetect: DSP Dead!\n") );
311 return ECHOSTATUS_DSP_DEAD
;
315 // Map the DSP clock detect bits to the generic driver clock detect bits
317 DWORD dwClocksFromDsp
= GetDspCommObject()->GetInputClockDetect();
319 dwClockDetectBits
= ECHO_CLOCK_BIT_INTERNAL
;
321 if (0 != (dwClocksFromDsp
& GLDM_CLOCK_DETECT_BIT_SPDIF
))
322 dwClockDetectBits
|= ECHO_CLOCK_BIT_SPDIF
;
324 return ECHOSTATUS_OK
;
326 } // GetInputClockDetect