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
operator new(size_t Size)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
operator delete(PVOID pVoid)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
CMona(PCOsSupport pOsSupport)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
~CMona()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
InitHw()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 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
GetCapabilities(PECHOGALS_CAPS pCapabilities)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
QueryAudioSampleRate(DWORD dwSampleRate)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
QuerySampleRateRange(DWORD & dwMinRate,DWORD & dwMaxRate)262 void 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
GetInputClockDetect(DWORD & dwClockDetectBits)282 ECHOSTATUS 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