1 // ****************************************************************************
5 // Implementation file for the CMona 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 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
40 /****************************************************************************
42 Construction and destruction
44 ****************************************************************************/
46 //===========================================================================
48 // Overload new & delete so memory for this object is allocated
49 // from non-paged memory.
51 //===========================================================================
53 PVOID
CMona::operator new( size_t Size
)
58 Status
= OsAllocateNonPaged(Size
,&pMemory
);
60 if ( (ECHOSTATUS_OK
!= Status
) || (NULL
== pMemory
))
62 ECHO_DEBUGPRINTF(("CMona::operator new - memory allocation failed\n"));
68 memset( pMemory
, 0, Size
);
73 } // PVOID CMona::operator new( size_t Size )
76 VOID
CMona::operator delete( PVOID pVoid
)
78 if ( ECHOSTATUS_OK
!= OsFreeNonPaged( pVoid
) )
80 ECHO_DEBUGPRINTF(("CMona::operator delete memory free failed\n"));
82 } // VOID CMona::operator delete( PVOID pVoid )
85 //===========================================================================
87 // Constructor and destructor
89 //===========================================================================
91 CMona::CMona( PCOsSupport pOsSupport
)
92 : CEchoGals( pOsSupport
)
94 ECHO_DEBUGPRINTF( ( "CMona::CMona() is born!\n" ) );
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
;
104 ECHO_DEBUGPRINTF( ( "CMona::~CMona() is toast!\n" ) );
110 /****************************************************************************
112 Setup and hardware initialization
114 ****************************************************************************/
116 //===========================================================================
118 // Every card has an InitHw method
120 //===========================================================================
122 ECHOSTATUS
CMona::InitHw()
127 // Call the base method
129 if ( ECHOSTATUS_OK
!= ( Status
= CEchoGals::InitHw() ) )
133 // Create the DSP comm object
135 ECHO_ASSERT(NULL
== m_pDspCommObject
);
136 m_pDspCommObject
= new CMonaDspCommObject( (PDWORD
) m_pvSharedMemory
,
138 if (NULL
== m_pDspCommObject
)
140 ECHO_DEBUGPRINTF(("CMona::InitHw - could not create DSP comm object\n"));
141 return ECHOSTATUS_NO_MEM
;
145 // Load the DSP, the PCI card ASIC, and the external box ASIC
147 GetDspCommObject()->LoadFirmware();
148 if ( GetDspCommObject()->IsBoardBad() )
149 return ECHOSTATUS_DSP_DEAD
;
152 // Clear the "bad board" flag; set the flags to indicate that
153 // Mona can handle super-interleave and supports the digital
156 m_wFlags
&= ~ECHOGALS_FLAG_BADBOARD
;
157 m_wFlags
|= ECHOGALS_ROFLAG_SUPER_INTERLEAVE_OK
|
158 ECHOGALS_ROFLAG_DIGITAL_IN_AUTOMUTE
;
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 the digital mode to S/PDIF RCA
171 SetDigitalMode( DIGITAL_MODE_SPDIF_RCA
);
174 // Set the S/PDIF output format to "professional"
176 SetProfessionalSpdif( TRUE
);
179 // Get default sample rate from DSP
181 m_dwSampleRate
= GetDspCommObject()->GetSampleRate();
183 ECHO_DEBUGPRINTF( ( "CMona::InitHw()\n" ) );
186 } // ECHOSTATUS CMona::InitHw()
191 /****************************************************************************
193 Informational methods
195 ****************************************************************************/
197 //===========================================================================
199 // Override GetCapabilities to enumerate unique capabilties for this card
201 //===========================================================================
203 ECHOSTATUS
CMona::GetCapabilities
205 PECHOGALS_CAPS pCapabilities
210 Status
= GetBaseCapabilities(pCapabilities
);
211 if ( ECHOSTATUS_OK
!= Status
)
214 pCapabilities
->dwInClockTypes
|= ECHO_CLOCK_BIT_WORD
|
215 ECHO_CLOCK_BIT_SPDIF
|
220 } // ECHOSTATUS CMona::GetCapabilities
223 //===========================================================================
225 // QueryAudioSampleRate is used to find out if this card can handle a
226 // given sample rate.
228 //===========================================================================
230 ECHOSTATUS
CMona::QueryAudioSampleRate
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 )
246 ("CMona::QueryAudioSampleRate() - rate %ld invalid\n",dwSampleRate
) );
247 return ECHOSTATUS_BAD_FORMAT
;
249 if ( dwSampleRate
>= 88200 && DIGITAL_MODE_ADAT
== GetDigitalMode() )
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
;
257 ECHO_DEBUGPRINTF( ( "CMona::QueryAudioSampleRate()\n" ) );
258 return ECHOSTATUS_OK
;
259 } // ECHOSTATUS CMona::QueryAudioSampleRate
262 void CMona::QuerySampleRateRange(DWORD
&dwMinRate
,DWORD
&dwMaxRate
)
269 //===========================================================================
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.
275 // You should use this information to determine which clocks the user is
276 // allowed to select.
278 // Mona supports S/PDIF, word, and ADAT input clocks.
280 //===========================================================================
282 ECHOSTATUS
CMona::GetInputClockDetect(DWORD
&dwClockDetectBits
)
284 //ECHO_DEBUGPRINTF(("CMona::GetInputClockDetect\n"));
286 if ( NULL
== GetDspCommObject() || GetDspCommObject()->IsBoardBad() )
288 ECHO_DEBUGPRINTF( ("CMona::GetInputClockDetect: DSP Dead!\n") );
289 return ECHOSTATUS_DSP_DEAD
;
293 // Map the DSP clock detect bits to the generic driver clock detect bits
295 DWORD dwClocksFromDsp
= GetDspCommObject()->GetInputClockDetect();
297 dwClockDetectBits
= ECHO_CLOCK_BIT_INTERNAL
;
299 if (0 != (dwClocksFromDsp
& GML_CLOCK_DETECT_BIT_SPDIF
))
300 dwClockDetectBits
|= ECHO_CLOCK_BIT_SPDIF
;
302 if (0 != (dwClocksFromDsp
& GML_CLOCK_DETECT_BIT_ADAT
))
303 dwClockDetectBits
|= ECHO_CLOCK_BIT_ADAT
;
305 if (0 != (dwClocksFromDsp
& GML_CLOCK_DETECT_BIT_WORD
))
306 dwClockDetectBits
|= ECHO_CLOCK_BIT_WORD
;
308 return ECHOSTATUS_OK
;
310 } // GetInputClockDetect