xref: /haiku/src/add-ons/kernel/drivers/audio/echo/generic/CDspCommObject.h (revision 7749d0bb0c358a3279b1b9cc76d8376e900130a5)
1 // ****************************************************************************
2 //
3 //		CDspCommObject.H
4 //
5 //		Include file for EchoGals generic driver DSP interface base class.
6 //
7 // ----------------------------------------------------------------------------
8 //
9 // ----------------------------------------------------------------------------
10 //
11 // This file is part of Echo Digital Audio's generic driver library.
12 // Copyright Echo Digital Audio Corporation (c) 1998 - 2005
13 // All rights reserved
14 // www.echoaudio.com
15 //
16 // This library is free software; you can redistribute it and/or
17 // modify it under the terms of the GNU Lesser General Public
18 // License as published by the Free Software Foundation; either
19 // version 2.1 of the License, or (at your option) any later version.
20 //
21 // This library is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24 // Lesser General Public License for more details.
25 //
26 // You should have received a copy of the GNU Lesser General Public
27 // License along with this library; if not, write to the Free Software
28 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 //
30 // ****************************************************************************
31 
32 #ifndef _DSPCOMMOBJECT_
33 #define _DSPCOMMOBJECT_
34 
35 #ifdef _DEBUG
36 #ifdef ECHO_WDM
37 #pragma optimize("",off)
38 #endif
39 #endif
40 
41 #ifdef _WIN32
42 
43 //	Must match structure alignment w/DSP
44 #pragma pack( push, 2 )
45 
46 #endif
47 
48 #include "OsSupport.h"
49 #include "CDaffyDuck.h"
50 
51 /****************************************************************************
52 
53 	Lots of different defines for the different cards
54 
55  ****************************************************************************/
56 
57 
58 //==================================================================================
59 //
60 // Macros to convert to and from generic driver mixer values.  Since it can be tough
61 // to do floating point math in a driver, the generic driver uses fixed-point values.
62 // The numbers are in a 24.8 format; that is, the upper 24 bits are the integer part
63 // of the number and the lower 8 bits represent the fractional part.  In this scheme,
64 // a value of 0x180 would be equal to 1.5.
65 //
66 // Since the DSP usually wants 8 bit integer gains, the following macros are useful.
67 //
68 //==================================================================================
69 
70 #define GENERIC_TO_DSP(iValue) 	((iValue + 0x80) >> 8)
71 #define DSP_TO_GENERIC(iValue)	(iValue << 8)
72 
73 
74 //==================================================================================
75 //
76 //	Max inputs and outputs
77 //
78 //==================================================================================
79 
80 #define DSP_MAXAUDIOINPUTS			16				// Max audio input channels
81 #define DSP_MAXAUDIOOUTPUTS		16				// Max audio output channels
82 #define DSP_MAXPIPES					32				// Max total pipes (input + output)
83 
84 
85 //==================================================================================
86 //
87 //	These are the offsets for the memory-mapped DSP registers; the DSP base
88 // address is treated as the start of a DWORD array.
89 //
90 //==================================================================================
91 
92 #define	CHI32_CONTROL_REG					4
93 #define	CHI32_STATUS_REG					5
94 #define	CHI32_VECTOR_REG					6
95 #define	CHI32_DATA_REG						7
96 
97 
98 //==================================================================================
99 //
100 //	Interesting bits within the DSP registers
101 //
102 //==================================================================================
103 
104 #define	CHI32_VECTOR_BUSY					0x00000001
105 #define	CHI32_STATUS_REG_HF3				0x00000008
106 #define	CHI32_STATUS_REG_HF4				0x00000010
107 #define	CHI32_STATUS_REG_HF5				0x00000020
108 #define	CHI32_STATUS_HOST_READ_FULL	0x00000004
109 #define	CHI32_STATUS_HOST_WRITE_EMPTY	0x00000002
110 #define 	CHI32_STATUS_IRQ			      0x00000040
111 
112 
113 //==================================================================================
114 //
115 // DSP commands sent via slave mode; these are sent to the DSP by
116 // CDspCommObject::Write_DSP
117 //
118 //==================================================================================
119 
120 #define  DSP_FNC_SET_COMMPAGE_ADDR				0x02
121 #define	DSP_FNC_LOAD_LAYLA_ASIC					0xa0
122 #define	DSP_FNC_LOAD_GINA24_ASIC				0xa0
123 #define 	DSP_FNC_LOAD_MONA_PCI_CARD_ASIC		0xa0
124 #define 	DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC	0xa0
125 #define 	DSP_FNC_LOAD_MONA_EXTERNAL_ASIC		0xa1
126 #define 	DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC	0xa1
127 #define  DSP_FNC_LOAD_3G_ASIC						0xa0
128 
129 
130 //==================================================================================
131 //
132 // Defines to handle the MIDI input state engine; these are used to properly
133 // extract MIDI time code bytes and their timestamps from the MIDI input stream.
134 //
135 //==================================================================================
136 
137 #define	MIDI_IN_STATE_NORMAL				0
138 #define	MIDI_IN_STATE_TS_HIGH			1
139 #define	MIDI_IN_STATE_TS_LOW				2
140 #define	MIDI_IN_STATE_F1_DATA			3
141 
142 #define	MIDI_IN_SKIP_DATA					((DWORD)-1)
143 
144 
145 /*------------------------------------------------------------------------------------
146 
147 Setting the sample rates on Layla24 is somewhat schizophrenic.
148 
149 For standard rates, it works exactly like Mona and Gina24.  That is, for
150 8, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the
151 appropriate bits in the control register and write the control register.
152 
153 In order to support MIDI time code sync (and possibly SMPTE LTC sync in
154 the future), Layla24 also has "continuous sample rate mode".  In this mode,
155 Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or
156 50 to 100 kHz inclusive for double speed mode.
157 
158 To use continuous mode:
159 
160 -Set the clock select bits in the control register to 0xe (see the #define
161  below)
162 
163 -Set double-speed mode if you want to use sample rates above 50 kHz
164 
165 -Write the control register as you would normally
166 
167 -Now, you need to set the frequency register. First, you need to determine the
168  value for the frequency register.  This is given by the following formula:
169 
170 frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2
171 
172 Note the #define below for the magic number
173 
174 -Wait for the DSP handshake
175 -Write the frequency_reg value to the dwSampleRate field of the comm page
176 -Send the vector command SET_LAYLA24_FREQUENCY_REG (see vmonkey.h)
177 
178 Once you have set the control register up for continuous mode, you can just
179 write the frequency register to change the sample rate.  This could be
180 used for MIDI time code sync. For MTC sync, the control register is set for
181 continuous mode.  The driver then just keeps writing the
182 SET_LAYLA24_FREQUENCY_REG command.
183 
184 ----------------------------------------------------------------------------------*/
185 
186 #define	LAYLA24_MAGIC_NUMBER						677376000
187 #define	LAYLA24_CONTINUOUS_CLOCK				0x000e
188 
189 
190 //==================================================================================
191 //
192 // DSP vector commands
193 //
194 //==================================================================================
195 
196 #define	DSP_VC_RESET							0x80ff
197 
198 #ifndef DSP_56361
199 
200 //
201 // Vector commands for families that only use the 56301
202 // Only used for Darla20, Gina20, Layla20, and Darla24
203 //
204 #define	DSP_VC_ACK_INT							0x8073
205 #define	DSP_VC_SET_VMIXER_GAIN				0x0000	// Not used, only for compile
206 #define	DSP_VC_START_TRANSFER				0x0075	// Handshke rqd.
207 #define	DSP_VC_METERS_ON						0x0079
208 #define	DSP_VC_METERS_OFF						0x007b
209 #define	DSP_VC_UPDATE_OUTVOL					0x007d	// Handshke rqd.
210 #define	DSP_VC_UPDATE_INGAIN					0x007f	// Handshke rqd.
211 #define	DSP_VC_ADD_AUDIO_BUFFER				0x0081	// Handshke rqd.
212 #define	DSP_VC_TEST_ASIC						0x00eb
213 #define	DSP_VC_UPDATE_CLOCKS					0x00ef	// Handshke rqd.
214 #define 	DSP_VC_SET_LAYLA_SAMPLE_RATE		0x00f1	// Handshke rqd.
215 #define	DSP_VC_SET_GD_AUDIO_STATE			0x00f1	// Handshke rqd.
216 #define	DSP_VC_WRITE_CONTROL_REG			0x00f1	// Handshke rqd.
217 #define 	DSP_VC_MIDI_WRITE						0x00f5	// Handshke rqd.
218 #define 	DSP_VC_STOP_TRANSFER					0x00f7	// Handshke rqd.
219 #define	DSP_VC_UPDATE_FLAGS					0x00fd	// Handshke rqd.
220 #define 	DSP_VC_GO_COMATOSE					0x00f9
221 
222 #else
223 
224 //
225 // Vector commands for families that use either the 56301 or 56361
226 //
227 #define	DSP_VC_ACK_INT							0x80F5
228 #define	DSP_VC_SET_VMIXER_GAIN				0x00DB	// Handshke rqd.
229 #define	DSP_VC_START_TRANSFER				0x00DD	// Handshke rqd.
230 #define	DSP_VC_METERS_ON						0x00EF
231 #define	DSP_VC_METERS_OFF						0x00F1
232 #define	DSP_VC_UPDATE_OUTVOL					0x00E3	// Handshke rqd.
233 #define	DSP_VC_UPDATE_INGAIN					0x00E5	// Handshke rqd.
234 #define	DSP_VC_ADD_AUDIO_BUFFER				0x00E1	// Handshke rqd.
235 #define	DSP_VC_TEST_ASIC						0x00ED
236 #define	DSP_VC_UPDATE_CLOCKS					0x00E9	// Handshke rqd.
237 #define	DSP_VC_SET_LAYLA24_FREQUENCY_REG	0x00E9	// Handshke rqd.
238 #define 	DSP_VC_SET_LAYLA_SAMPLE_RATE		0x00EB	// Handshke rqd.
239 #define	DSP_VC_SET_GD_AUDIO_STATE			0x00EB	// Handshke rqd.
240 #define	DSP_VC_WRITE_CONTROL_REG			0x00EB	// Handshke rqd.
241 #define 	DSP_VC_MIDI_WRITE						0x00E7	// Handshke rqd.
242 #define 	DSP_VC_STOP_TRANSFER					0x00DF	// Handshke rqd.
243 #define	DSP_VC_UPDATE_FLAGS					0x00FB	// Handshke rqd.
244 #define 	DSP_VC_GO_COMATOSE					0x00d9
245 
246 #ifdef SUPERMIX
247 #define	DSP_VC_TRIGGER							0x00f3
248 #endif
249 
250 #endif
251 
252 
253 //==================================================================================
254 //
255 //	Timeouts
256 //
257 //==================================================================================
258 
259 #define HANDSHAKE_TIMEOUT		20000		//	SendVector command timeout in microseconds
260 #define MIDI_OUT_DELAY_USEC	2000		// How long to wait after MIDI fills up
261 
262 
263 //==================================================================================
264 //
265 //	Flags for dwFlags field in the comm page
266 //
267 //==================================================================================
268 
269 #define	DSP_FLAG_MIDI_INPUT				0x0001	// Enable MIDI input
270 #define	DSP_FLAG_SPDIF_NONAUDIO			0x0002	// Sets the "non-audio" bit in the S/PDIF out
271 																// status bits.  Clear this flag for audio data;
272 																// set it for AC3 or WMA or some such
273 #define	DSP_FLAG_PROFESSIONAL_SPDIF	0x0008	// 1 Professional, 0 Consumer
274 
275 #ifdef SUPERMIX
276 #define	DSP_FLAG_SUPERMIX_SRC			0x0080	// Turn on sample rate conversion for supermixer
277 #endif
278 
279 
280 
281 //==================================================================================
282 //
283 //	Clock detect bits reported by the DSP for Gina20, Layla20, Darla24, and Mia
284 //
285 //==================================================================================
286 
287 #define GLDM_CLOCK_DETECT_BIT_WORD		0x0002
288 #define GLDM_CLOCK_DETECT_BIT_SUPER		0x0004
289 #define GLDM_CLOCK_DETECT_BIT_SPDIF		0x0008
290 #define GLDM_CLOCK_DETECT_BIT_ESYNC		0x0010
291 
292 
293 //==================================================================================
294 //
295 //	Clock detect bits reported by the DSP for Gina24, Mona, and Layla24
296 //
297 //==================================================================================
298 
299 #define GML_CLOCK_DETECT_BIT_WORD96		0x0002
300 #define GML_CLOCK_DETECT_BIT_WORD48		0x0004
301 #define GML_CLOCK_DETECT_BIT_SPDIF48	0x0008
302 #define GML_CLOCK_DETECT_BIT_SPDIF96	0x0010
303 #define GML_CLOCK_DETECT_BIT_WORD		(GML_CLOCK_DETECT_BIT_WORD96|GML_CLOCK_DETECT_BIT_WORD48)
304 #define GML_CLOCK_DETECT_BIT_SPDIF		(GML_CLOCK_DETECT_BIT_SPDIF48|GML_CLOCK_DETECT_BIT_SPDIF96)
305 #define GML_CLOCK_DETECT_BIT_ESYNC		0x0020
306 #define GML_CLOCK_DETECT_BIT_ADAT		0x0040
307 
308 
309 //==================================================================================
310 //
311 //	Gina/Darla clock states
312 //
313 //==================================================================================
314 
315 #define GD_CLOCK_NOCHANGE			0
316 #define GD_CLOCK_44					1
317 #define GD_CLOCK_48					2
318 #define GD_CLOCK_SPDIFIN			3
319 #define GD_CLOCK_UNDEF				0xff
320 
321 
322 //==================================================================================
323 //
324 //	Gina/Darla S/PDIF status bits
325 //
326 //==================================================================================
327 
328 #define GD_SPDIF_STATUS_NOCHANGE	0
329 #define GD_SPDIF_STATUS_44			1
330 #define GD_SPDIF_STATUS_48			2
331 #define GD_SPDIF_STATUS_UNDEF		0xff
332 
333 
334 //==================================================================================
335 //
336 //	Layla20 output clocks
337 //
338 //==================================================================================
339 
340 #define LAYLA20_OUTPUT_CLOCK_SUPER	0
341 #define LAYLA20_OUTPUT_CLOCK_WORD	1
342 
343 
344 //==================================================================================
345 //
346 //	Return values from the DSP when ASIC is loaded
347 //
348 //==================================================================================
349 
350 #define ASIC_LOADED					0x1
351 #define ASIC_NOT_LOADED				0x0
352 
353 
354 //==================================================================================
355 //
356 ////	DSP Audio formats
357 //
358 // These are the audio formats that the DSP can transfer
359 // via input and output pipes.  LE means little-endian,
360 // BE means big-endian.
361 //
362 // DSP_AUDIOFORM_MS_8
363 //
364 // 	8-bit mono unsigned samples.  For playback,
365 //		mono data is duplicated out the left and right channels
366 // 	of the output bus.  The "MS" part of the name
367 //		means mono->stereo.
368 //
369 //	DSP_AUDIOFORM_MS_16LE
370 //
371 //		16-bit signed little-endian mono samples.  Playback works
372 //		like the previous code.
373 //
374 //	DSP_AUDIOFORM_MS_24LE
375 //
376 //		24-bit signed little-endian mono samples.  Data is packed
377 //    three bytes per sample; if you had two samples 0x112233 and 0x445566
378 //    they would be stored in memory like this: 33 22 11 66 55 44.
379 //
380 //	DSP_AUDIOFORM_MS_32LE
381 //
382 //		24-bit signed little-endian mono samples in a 32-bit
383 //		container.  In other words, each sample is a 32-bit signed
384 //		integer, where the actual audio data is left-justified
385 //		in the 32 bits and only the 24 most significant bits are valid.
386 //
387 //	DSP_AUDIOFORM_SS_8
388 //	DSP_AUDIOFORM_SS_16LE
389 // DSP_AUDIOFORM_SS_24LE
390 //	DSP_AUDIOFORM_SS_32LE
391 //
392 //		Like the previous ones, except now with stereo interleaved
393 //		data.  "SS" means stereo->stereo.
394 //
395 // DSP_AUDIOFORM_MM_32LE
396 //
397 //		Similar to DSP_AUDIOFORM_MS_32LE, except that the mono
398 //		data is not duplicated out both the left and right outputs.
399 //		This mode is used by the ASIO driver.  Here, "MM" means
400 //		mono->mono.
401 //
402 //	DSP_AUDIOFORM_MM_32BE
403 //
404 //		Just like DSP_AUDIOFORM_MM_32LE, but now the data is
405 //		in big-endian format.
406 //
407 //==================================================================================
408 
409 #define DSP_AUDIOFORM_MS_8			0		// 8 bit mono
410 #define DSP_AUDIOFORM_MS_16LE		1		// 16 bit mono
411 #define DSP_AUDIOFORM_MS_24LE		2		// 24 bit mono
412 #define DSP_AUDIOFORM_MS_32LE		3		// 32 bit mono
413 #define DSP_AUDIOFORM_SS_8			4		// 8 bit stereo
414 #define DSP_AUDIOFORM_SS_16LE		5		// 16 bit stereo
415 #define DSP_AUDIOFORM_SS_24LE		6		// 24 bit stereo
416 #define DSP_AUDIOFORM_SS_32LE		7		// 32 bit stereo
417 #define DSP_AUDIOFORM_MM_32LE		8		// 32 bit mono->mono little-endian
418 #define DSP_AUDIOFORM_MM_32BE		9		// 32 bit mono->mono big-endian
419 #define DSP_AUDIOFORM_SS_32BE		10		// 32 bit stereo big endian
420 #define DSP_AUDIOFORM_INVALID		0xFF	// Invalid audio format
421 
422 
423 //==================================================================================
424 //
425 // Super-interleave is defined as interleaving by 4 or more.  Darla20 and Gina20
426 // do not support super interleave.
427 //
428 // 16 bit, 24 bit, and 32 bit little endian samples are supported for super
429 // interleave.  The interleave factor must be even.  16 - way interleave is the
430 // current maximum, so you can interleave by 4, 6, 8, 10, 12, 14, and 16.
431 //
432 // The actual format code is derived by taking the define below and or-ing with
433 // the interleave factor.  So, 32 bit interleave by 6 is 0x86 and
434 // 16 bit interleave by 16 is (0x40 | 0x10) = 0x50.
435 //
436 //==================================================================================
437 
438 #define DSP_AUDIOFORM_SUPER_INTERLEAVE_16LE	0x40
439 #define DSP_AUDIOFORM_SUPER_INTERLEAVE_24LE	0xc0
440 #define DSP_AUDIOFORM_SUPER_INTERLEAVE_32LE	0x80
441 
442 
443 //==================================================================================
444 //
445 //	Gina24, Mona, and Layla24 control register defines
446 //
447 //==================================================================================
448 
449 #define GML_CONVERTER_ENABLE		0x0010
450 #define GML_SPDIF_PRO_MODE			0x0020		// Professional S/PDIF == 1, consumer == 0
451 #define GML_SPDIF_SAMPLE_RATE0	0x0040
452 #define GML_SPDIF_SAMPLE_RATE1	0x0080
453 #define GML_SPDIF_TWO_CHANNEL		0x0100		// 1 == two channels, 0 == one channel
454 #define GML_SPDIF_NOT_AUDIO		0x0200
455 #define GML_SPDIF_COPY_PERMIT		0x0400
456 #define GML_SPDIF_24_BIT			0x0800		// 1 == 24 bit, 0 == 20 bit
457 #define GML_ADAT_MODE				0x1000		// 1 == ADAT mode, 0 == S/PDIF mode
458 #define GML_SPDIF_OPTICAL_MODE	0x2000		// 1 == optical mode, 0 == RCA mode
459 #define GML_DOUBLE_SPEED_MODE		0x4000		// 1 == double speed, 0 == single speed
460 
461 #define GML_DIGITAL_IN_AUTO_MUTE	0x800000
462 
463 #define GML_96KHZ						(0x0 | GML_DOUBLE_SPEED_MODE)
464 #define GML_88KHZ						(0x1 | GML_DOUBLE_SPEED_MODE)
465 #define GML_48KHZ						0x2
466 #define GML_44KHZ						0x3
467 #define GML_32KHZ						0x4
468 #define GML_22KHZ						0x5
469 #define GML_16KHZ						0x6
470 #define GML_11KHZ						0x7
471 #define GML_8KHZ						0x8
472 #define GML_SPDIF_CLOCK				0x9
473 #define GML_ADAT_CLOCK				0xA
474 #define GML_WORD_CLOCK				0xB
475 #define GML_ESYNC_CLOCK				0xC
476 #define GML_ESYNCx2_CLOCK			0xD
477 
478 #define GML_CLOCK_CLEAR_MASK			0xffffbff0
479 #define GML_SPDIF_RATE_CLEAR_MASK   (~(GML_SPDIF_SAMPLE_RATE0|GML_SPDIF_SAMPLE_RATE1))
480 #define GML_DIGITAL_MODE_CLEAR_MASK	0xffffcfff
481 #define GML_SPDIF_FORMAT_CLEAR_MASK	0xfffff01f
482 
483 
484 //==================================================================================
485 //
486 //	Mia sample rate and clock setting constants
487 //
488 //==================================================================================
489 
490 #define MIA_32000		0x0040
491 #define MIA_44100		0x0042
492 #define MIA_48000		0x0041
493 #define MIA_88200		0x0142
494 #define MIA_96000		0x0141
495 
496 #define MIA_SPDIF		0x00000044
497 #define MIA_SPDIF96	0x00000144
498 
499 #define MIA_MIDI_REV	1				// Must be Mia rev 1 for MIDI support
500 
501 
502 //==================================================================================
503 //
504 // Gina20 & Layla20 have input gain controls for the analog inputs;
505 // this is the magic number for the hardware that gives you 0 dB at -10.
506 //
507 //==================================================================================
508 
509 #define GL20_INPUT_GAIN_MAGIC_NUMBER	0xC8
510 
511 
512 //==================================================================================
513 //
514 //	Defines how much time must pass between DSP load attempts
515 //
516 //==================================================================================
517 
518 #define DSP_LOAD_ATTEMPT_PERIOD	1000000L	// One million microseconds == one second
519 
520 
521 //==================================================================================
522 //
523 // Size of arrays for the comm page.  MAX_PLAY_TAPS and MAX_REC_TAPS are no longer
524 // used, but the sizes must still be right for the DSP to see the comm page correctly.
525 //
526 //==================================================================================
527 
528 #define MONITOR_ARRAY_SIZE			0x180
529 #define VMIXER_ARRAY_SIZE			0x40
530 #define CP_MIDI_OUT_BUFFER_SIZE	32
531 #define CP_MIDI_IN_BUFFER_SIZE 	256
532 #define MAX_PLAY_TAPS				168
533 #define MAX_REC_TAPS					192
534 
535 #define DSP_MIDI_OUT_FIFO_SIZE	64
536 
537 
538 //==================================================================================
539 //
540 //	Macros for reading and writing DSP registers
541 //
542 //==================================================================================
543 
544 #ifndef READ_REGISTER_ULONG
545 #define READ_REGISTER_ULONG(ptr)		( *(ptr) )
546 #endif
547 
548 #ifndef WRITE_REGISTER_ULONG
549 #define WRITE_REGISTER_ULONG(ptr,val)	*(ptr) = val
550 #endif
551 
552 
553 /****************************************************************************
554 
555 	The comm page.  This structure is read and written by the DSP; the
556 	DSP code is a firm believer in the byte offsets written in the comments
557 	at the end of each line.  This structure should not be changed.
558 
559 	Any reads from or writes to this structure should be in little-endian
560 	format.
561 
562  ****************************************************************************/
563 
564 typedef struct
565 {
566 	DWORD				dwCommSize;				// size of this object							0x000	4
567 
568 	DWORD				dwFlags;					// See Appendix A below							0x004	4
569 	DWORD				dwUnused;				// Unused entry									0x008	4
570 
571 	DWORD				dwSampleRate;			// Card sample rate in Hz						0x00c	4
572 	DWORD				dwHandshake;			// DSP command handshake						0x010	4
573 	CChMaskDsp		cmdStart;				// Chs. to start mask							0x014	4
574 	CChMaskDsp		cmdStop;					// Chs. to stop mask								0x018	4
575 	CChMaskDsp		cmdReset;				// Chs. to reset mask							0x01c	4
576 	WORD				wAudioFormat[ DSP_MAXPIPES ];
577               									// Chs. audio format								0x020	16*2*2
578 	DUCKENTRY		DuckListPhys[ DSP_MAXPIPES ];
579      												// Chs. Physical duck addrs					0x060	16*2*8
580 	DWORD				dwPosition[ DSP_MAXPIPES ];
581 													// Positions for ea. ch.						0x160	16*2*4
582 	BYTE				VUMeter[ DSP_MAXPIPES ];
583 													// VU meters										0x1e0	16*2*1
584 	BYTE				PeakMeter[ DSP_MAXPIPES ];
585 													// Peak meters										0x200	16*2*1
586 	BYTE				OutLineLevel[ DSP_MAXAUDIOOUTPUTS ];
587 													// Output gain										0x220	16*1
588 	BYTE				InLineLevel[ DSP_MAXAUDIOINPUTS ];
589 													// Input gain										0x230	16*1
590 	BYTE				byMonitors[ MONITOR_ARRAY_SIZE ];
591 													// Monitor map										0x240	0x180
592 	DWORD				dwPlayCoeff[ MAX_PLAY_TAPS ];
593 													// Gina/Darla play filters - obsolete		0x3c0	168*4
594 	DWORD				dwRecCoeff [ MAX_REC_TAPS ];
595 													// Gina/Darla record filters - obsolete	0x660	192*4
596 	WORD				wMidiInData[ CP_MIDI_IN_BUFFER_SIZE ];
597 													// MIDI input data transfer buffer			0x960	256*2
598 	BYTE				byGDClockState;		// Chg Gina/Darla clock state					0xb60	4
599 	BYTE				byGDSpdifStatus;		// Chg. Gina/Darla S/PDIF state
600 	BYTE				byGDResamplerState;	// Should always be 3
601 	BYTE				byFiller2;
602 	CChMaskDsp		cmdNominalLevel;
603 													// -10 level enable mask						0xb64	4
604 	WORD				wInputClock; 			// Chg. Input clock state
605 	WORD				wOutputClock; 			// Chg. Output clock state						0xb68
606 	DWORD				dwStatusClocks;	 	// Current Input clock state					0xb6c	4
607 
608 	DWORD				dwExtBoxStatus;		// External box connected or not				0xb70 4
609 	DWORD				dwUnused2;				// filler											0xb74	4
610 	DWORD				dwMidiOutFreeCount;	// # of bytes free in MIDI output FIFO		0xb78	4
611 	DWORD 			dwUnused3;				//                                        0xb7c	4
612 	DWORD				dwControlReg;			// Mona, Gina24, Layla24 and 3G control 	0xb80 4
613 	DWORD				dw3gFreqReg;			// 3G frequency register						0xb84	4
614 	BYTE				byFiller[24];			// filler											0xb88
615 	BYTE				byVmixerLevel[ VMIXER_ARRAY_SIZE ];
616 													// Vmixer levels									0xba0 64
617 	BYTE				byMidiOutData[ CP_MIDI_OUT_BUFFER_SIZE ];
618 													// MIDI output data								0xbe0	32
619 } DspCommPage, *PDspCommPage;
620 
621 
622 /****************************************************************************
623 
624 	CDspCommObject is the class which wraps both the comm page and the
625 	DSP registers.  CDspCommObject talks directly to the hardware; anyone
626 	who wants to do something to the hardware goes through CDspCommObject or
627 	one of the derived classes.
628 
629 	Note that an instance of CDspCommObject is never actually created; it
630 	is treated as an abstract base class.
631 
632  ****************************************************************************/
633 
634 class CDspCommObject
635 {
636 protected:
637 	volatile PDspCommPage m_pDspCommPage;		// Physical memory seen by DSP
638 	PPAGE_BLOCK		m_pDspCommPageBlock;	// Physical memory info for COsSupport
639 
640  	//
641  	//	These members are not seen by the DSP; they are used internally by
642 	// this class.
643  	//
644 	WORD				m_wNumPipesOut;
645 	WORD				m_wNumPipesIn;
646 	WORD				m_wNumBussesOut;
647 	WORD				m_wNumBussesIn;
648 	WORD				m_wFirstDigitalBusOut;
649 	WORD				m_wFirstDigitalBusIn;
650 
651 	BOOL				m_fHasVmixer;
652 
653 	WORD				m_wNumMidiOut;			// # MIDI out channels
654 	WORD				m_wNumMidiIn;			// # MIDI in  channels
655 	PWORD 			m_pwDspCode;			// Current DSP code loaded, NULL if nothing loaded
656 	PWORD 			m_pwDspCodeToLoad;	// DSP code to load
657 	BOOL				m_bHasASIC;				// Set TRUE if card has an ASIC
658 	BOOL				m_bASICLoaded;			// Set TRUE when ASIC loaded
659 	DWORD				m_dwCommPagePhys;		// Physical addr of this object
660 	volatile PDWORD m_pdwDspRegBase;		// DSP's register base
661 	CChannelMask	m_cmActive;				// Chs. active mask
662 	BOOL				m_bBadBoard;			// Set TRUE if DSP won't load
663 													// or punks out
664 	WORD				m_wMeterOnCount;		// How many times meters have been
665 													// enabled
666 	PCOsSupport		m_pOsSupport;			// Ptr to OS specific methods & data
667 	CHAR				m_szCardName[ 20 ];
668 	BYTE				m_byDigitalMode;		// Digital mode (see DIGITAL_MODE_??
669 													//	defines in EchoGalsXface.h
670 	WORD				m_wInputClock;			// Currently selected input clock
671 	WORD				m_wOutputClock;		// Currently selected output clock
672 
673 	ULONGLONG		m_ullLastLoadAttemptTime;	// Last system time that the driver
674 															// attempted to load the DSP & ASIC
675 #ifdef DIGITAL_INPUT_AUTO_MUTE_SUPPORT
676 	BOOL				m_fDigitalInAutoMute;
677 #endif
678 
679 #ifdef MIDI_SUPPORT
680 	WORD				m_wMidiOnCount;		// Count MIDI enabled cmds
681 	ULONGLONG		m_ullMidiInTime;		// Last time MIDI in occured
682 	ULONGLONG		m_ullMidiOutTime;		// Last time MIDI out occured
683 	ULONGLONG		m_ullNextMidiWriteTime;	// Next time to try MIDI output
684 
685 	WORD				m_wMtcState;			// State for MIDI input parsing state machine
686 #endif
687 
688 protected :
689 
690 	virtual WORD ComputeAudioMonitorIndex
691 	(
692 		WORD	wBusOut,
693 		WORD	wBusIn
694 	)
695 	{
696 		return( wBusOut * m_wNumBussesIn + wBusIn );
697 	}
698 
699 	//
700 	//	Load code into DSP
701 	//
702 #ifdef DSP_56361
703 	virtual ECHOSTATUS InstallResidentLoader();
704 #endif
705 	virtual ECHOSTATUS LoadDSP( PWORD pCode );
706 
707 	//
708 	//	Read the serial number from DSP
709 	//
710 	virtual ECHOSTATUS	ReadSn();
711 
712 	//
713 	//	Load code into ASIC
714 	//
715 	virtual BOOL LoadASIC( DWORD dwCmd, PBYTE pCode, DWORD dwSize );
716 	virtual BOOL LoadASIC() { return TRUE; }
717 
718 	//
719 	//	Check status of ASIC - loaded or not loaded
720 	//
721 	virtual BOOL CheckAsicStatus();
722 
723 	//
724 	//	Write to DSP
725 	//
726 	ECHOSTATUS	Write_DSP( DWORD dwData );
727 
728 	//
729 	//	Read from DSP
730 	//
731 	ECHOSTATUS	Read_DSP( DWORD *pdwData );
732 
733 	//
734 	//	Get/Set handshake Flag
735 	//
736 	DWORD GetHandshakeFlag()
737 		{ ECHO_ASSERT( NULL != m_pDspCommPage );
738 		  return( SWAP( m_pDspCommPage->dwHandshake ) ); }
739 	void ClearHandshake()
740 		{ ECHO_ASSERT( NULL != m_pDspCommPage );
741 		  m_pDspCommPage->dwHandshake = 0; }
742 
743 	//
744 	//	Get/set DSP registers
745 	//
746 	DWORD GetDspRegister( DWORD dwIndex )
747 	{
748 		ECHO_ASSERT( NULL != m_pdwDspRegBase );
749 
750 		return READ_REGISTER_ULONG( m_pdwDspRegBase + dwIndex);
751 	}
752 
753 	void SetDspRegister( DWORD dwIndex, DWORD dwValue )
754 	{
755 		ECHO_ASSERT( NULL != m_pdwDspRegBase );
756 
757 		WRITE_REGISTER_ULONG( m_pdwDspRegBase + dwIndex, dwValue);
758 	}
759 
760 	//
761 	//	Set control register in CommPage
762 	//
763 	void SetControlRegister( DWORD dwControlRegister )
764 		{ ECHO_ASSERT( NULL != m_pDspCommPage );
765 		  m_pDspCommPage->dwControlReg = SWAP( dwControlRegister ); }
766 
767 	//
768 	//	Called after load firmware to restore old gains, meters on, monitors, etc.
769 	//
770 	virtual void RestoreDspSettings();
771 
772 	//
773 	// Send a vector command to the DSP
774 	//
775 	ECHOSTATUS SendVector( DWORD dwCommand );
776 
777 	//
778 	//	Wait for DSP to finish the last vector command
779 	//
780 	BOOL WaitForHandshake();
781 
782 	//
783 	// Send new input line setting to DSP
784 	//
785 	ECHOSTATUS UpdateAudioInLineLevel();
786 
787 public:
788 
789 	//
790 	//	Construction/destruction
791 	//
792 	CDspCommObject( PDWORD pdwRegBase, PCOsSupport pOsSupport );
793 	virtual ~CDspCommObject();
794 
795 	//
796 	//	Card information
797 	//
798 	virtual WORD GetCardType() = NULL;
799 										// Undefined, must be done in derived class
800 	const PCHAR GetCardName() { return( m_szCardName ); }
801 										// Must be init in derived class
802 
803 	//
804 	// Get mask with active pipes
805 	//
806 	void GetActivePipes
807 	(
808 		PCChannelMask	pChannelMask
809 	);
810 
811 	//
812 	// Basic info methods
813 	//
814 	WORD GetNumPipesOut()
815 	{
816 		return m_wNumPipesOut;
817 	}
818 
819 	WORD GetNumPipesIn()
820 	{
821 		return m_wNumPipesIn;
822 	}
823 
824 	WORD GetNumBussesOut()
825 	{
826 		return m_wNumBussesOut;
827 	}
828 
829 	WORD GetNumBussesIn()
830 	{
831 		return m_wNumBussesIn;
832 	}
833 
834 	WORD GetNumPipes()
835 	{
836 		return m_wNumPipesOut + m_wNumPipesIn;
837 	}
838 
839 	WORD GetNumBusses()
840 	{
841 		return m_wNumBussesOut + m_wNumBussesIn;
842 	}
843 
844 	WORD GetFirstDigitalBusOut()
845 	{
846 		return m_wFirstDigitalBusOut;
847 	}
848 
849 	WORD GetFirstDigitalBusIn()
850 	{
851 		return m_wFirstDigitalBusIn;
852 	}
853 
854 	BOOL HasVmixer()
855 	{
856 		return m_fHasVmixer;
857 	}
858 
859 	WORD GetNumMidiOutChannels()
860 		{ return( m_wNumMidiOut ); }
861 	WORD GetNumMidiInChannels()
862 		{ return( m_wNumMidiIn ); }
863 	WORD GetNumMidiChannels()
864 		{ return( m_wNumMidiIn + m_wNumMidiOut ); }
865 
866 	//
867 	// Get, set, and clear comm page flags
868 	//
869 	DWORD GetFlags()
870 		{
871 			return( SWAP( m_pDspCommPage->dwFlags ) );  }
872 	DWORD SetFlags( DWORD dwFlags )
873 		{
874 			DWORD dwCpFlags = SWAP( m_pDspCommPage->dwFlags );
875 			dwCpFlags |= dwFlags;
876 			m_pDspCommPage->dwFlags = SWAP( dwCpFlags );
877 
878 			if ( m_bASICLoaded && WaitForHandshake() )
879 				UpdateFlags();
880 		  return( GetFlags() );
881 		}
882 	DWORD ClearFlags( DWORD dwFlags )
883 		{
884 			DWORD dwCpFlags = SWAP( m_pDspCommPage->dwFlags );
885 			dwCpFlags &= ~dwFlags;
886 			m_pDspCommPage->dwFlags = SWAP( dwCpFlags );
887 
888 			if ( m_bASICLoaded && WaitForHandshake() )
889 				UpdateFlags();
890 			return( GetFlags() );
891 		}
892 
893 	//
894 	//	Returns currently selected input clock
895 	//
896 	WORD GetInputClock()
897 	{
898 		return m_wInputClock;
899 	}
900 
901 	//
902 	//	Returns what input clocks are currently detected
903 	//
904 	DWORD GetInputClockDetect()
905 		{ return( SWAP( m_pDspCommPage->dwStatusClocks ) ); }
906 
907 	//
908 	//	Returns currently selected output clock
909 	//
910 	WORD GetOutputClock()
911 	{
912 		return m_wOutputClock;
913 	}
914 
915 	//
916 	//	Returns control register
917 	//
918 	DWORD GetControlRegister()
919 		{ ECHO_ASSERT( NULL != m_pDspCommPage );
920 		  return SWAP( m_pDspCommPage->dwControlReg ); }
921 
922 	//
923 	//	Set input and output clocks
924 	//
925 	virtual ECHOSTATUS SetInputClock(WORD wClock);
926 	virtual ECHOSTATUS SetOutputClock(WORD wClock);
927 
928 	#ifdef COURT8_FAMILY
929 	virtual ECHOSTATUS SetPhoneBits(DWORD 	dwPhoneBits)
930 	{
931 		return ECHOSTATUS_NOT_SUPPORTED;
932 	}
933 	#endif
934 
935 	//
936 	//	Set digital mode
937 	//
938 	virtual ECHOSTATUS SetDigitalMode( BYTE byNewMode )
939 		{ return ECHOSTATUS_DIGITAL_MODE_NOT_SUPPORTED; }
940 
941 	//
942 	//	Get digital mode
943 	//
944 	virtual BYTE GetDigitalMode()
945 		{ return( m_byDigitalMode ); }
946 
947 	//
948 	//	Get mask of all supported digital modes.
949 	//	(See ECHOCAPS_HAS_DIGITAL_MODE_??? defines in EchoGalsXface.h)
950 	//
951 	//	Note: If the card does not have a digital mode switch
952 	//			then return 0 (no digital modes supported).
953 	//			Some legacy cards support S/PDIF as their only
954 	//			digital mode.  We still return 0 here because it
955 	//			is not switchable.
956 	//
957 	virtual DWORD GetDigitalModes()
958 		{ return( 0 ); }
959 
960 	//
961 	//	Return audio channel position in bytes
962 	//
963 	DWORD GetAudioPosition( WORD wPipeIndex )
964 		{ ECHO_ASSERT( wPipeIndex < ECHO_MAXAUDIOPIPES );
965 
966 		  return( ( wPipeIndex < ECHO_MAXAUDIOPIPES )
967 							? SWAP( m_pDspCommPage->dwPosition[ wPipeIndex ] )
968 							: 0  );  }
969 
970 	//
971 	// Reset the pipe position for a single pipe
972 	//
973 	void ResetPipePosition(WORD wPipeIndex)
974 	{
975 		if (wPipeIndex < ECHO_MAXAUDIOPIPES)
976 		{
977 			m_pDspCommPage->dwPosition[ wPipeIndex ] = 0;
978 		}
979 	}
980 
981 	//
982 	// Warning: Never write to the pointer returned by this
983 	// function!!!
984 	//
985 	//	The data pointed to by this pointer is in little-
986 	// endian format.
987 	//
988 	PDWORD GetAudioPositionPtr()
989 		{ return( m_pDspCommPage->dwPosition ); }
990 
991 	//
992 	// Get the current sample rate
993 	//
994 	virtual DWORD GetSampleRate()
995 	    { return( SWAP( m_pDspCommPage->dwSampleRate ) ); }
996 
997 	//
998 	//	Set the sample rate.
999 	//	Return rate that was set, 0xffffffff if error
1000 	//
1001 	virtual DWORD SetSampleRate( DWORD dwNewSampleRate ) = NULL;
1002 
1003 	//
1004 	//	Send current setting to DSP & return what it is
1005 	//
1006 	virtual DWORD SetSampleRate() = NULL;
1007 
1008 	//
1009 	// Start a group of pipes
1010 	//
1011 	ECHOSTATUS StartTransport
1012 	(
1013 		PCChannelMask	pChannelMask		// Pipes to start
1014 	);
1015 
1016 	//
1017 	// Stop a group of pipes
1018 	//
1019 	ECHOSTATUS StopTransport
1020 	(
1021 		PCChannelMask	pChannelMask
1022 	);
1023 
1024 	//
1025 	// Reset a group of pipes
1026 	//
1027 	ECHOSTATUS ResetTransport
1028 	(
1029 		PCChannelMask	pChannelMask
1030 	);
1031 
1032 #ifdef SUPERMIX
1033 	//
1034 	// Trigger this card for synced transport; used for Supermix mode
1035 	//
1036 	ECHOSTATUS TriggerTransport();
1037 #endif
1038 
1039 	//
1040 	//	See if any pipes are playing or recording
1041 	//
1042 	BOOL IsTransportActive()
1043 	{
1044 		return (FALSE == m_cmActive.IsEmpty());
1045 	}
1046 
1047 	//
1048 	// Tell DSP we added a buffer to a channel
1049 	//
1050 	ECHOSTATUS AddBuffer( WORD wPipeIndex );
1051 
1052 	//
1053 	// Add start of duck list for one channel to commpage so DSP can read it.
1054 	//
1055 	void SetAudioDuckListPhys( WORD wPipeIndex, DWORD dwNewPhysAdr );
1056 
1057 	//
1058 	// Read extended status register from the DSP
1059 	//
1060 	DWORD GetStatusReg()
1061 	{
1062 		return READ_REGISTER_ULONG( m_pdwDspRegBase + CHI32_STATUS_REG );
1063 	}
1064 
1065 	//
1066 	// Tell DSP to release the hardware interrupt
1067 	//
1068 	void AckInt()
1069 	{
1070 		m_pDspCommPage->wMidiInData[ 0 ] = 0;
1071 		SendVector( DSP_VC_ACK_INT );
1072 	}
1073 
1074 	//
1075 	// Overload new & delete so memory for this object is allocated
1076 	// from contiguous non-paged memory.
1077 	//
1078 	PVOID operator new( size_t Size );
1079 	VOID  operator delete( PVOID pVoid );
1080 
1081 	//
1082 	//	Get status of board
1083 	//
1084 	BOOL IsBoardBad()
1085 		{ return( m_bBadBoard ); }
1086 
1087 	//
1088 	//	Tell DSP flags have been updated
1089 	//
1090 	ECHOSTATUS UpdateFlags()
1091 	{
1092 		ECHO_DEBUGPRINTF(("CDspCommObject::UpdateFlags\n"));
1093 		ClearHandshake();
1094 		return( SendVector( DSP_VC_UPDATE_FLAGS ) );
1095 	}
1096 
1097 	//
1098 	//	Get/Set professional or consumer S/PDIF status
1099 	//
1100 	virtual BOOL IsProfessionalSpdif()
1101 		{
1102 			ECHO_DEBUGPRINTF(("CDspCommObject::IsProfessionalSpdif - flags are 0x%lx\n",
1103 									GetFlags()));
1104 			return( ( GetFlags() & DSP_FLAG_PROFESSIONAL_SPDIF ) ? TRUE : FALSE );
1105 		}
1106 
1107 	virtual void SetProfessionalSpdif( BOOL bNewStatus )
1108 		{
1109 			ECHO_DEBUGPRINTF(("CDspCommObject::SetProfessionalSpdif %d\n",bNewStatus));
1110 			if ( 0 != bNewStatus )
1111 				SetFlags( DSP_FLAG_PROFESSIONAL_SPDIF );
1112 			else
1113 				ClearFlags( DSP_FLAG_PROFESSIONAL_SPDIF );
1114 
1115 			ECHO_DEBUGPRINTF(("CDspCommObject::SetProfessionalSpdif - flags are now 0x%lx\n",
1116 									GetFlags()));
1117 		}
1118 
1119 	//
1120 	// Get/Set S/PDIF out non-audio status bit
1121 	//
1122 	virtual BOOL IsSpdifOutNonAudio()
1123 	{
1124 			return( ( GetFlags() & DSP_FLAG_SPDIF_NONAUDIO ) ? TRUE : FALSE );
1125 	}
1126 
1127 	virtual void SetSpdifOutNonAudio( BOOL bNonAudio)
1128 	{
1129 			if ( 0 != bNonAudio )
1130 				SetFlags( DSP_FLAG_SPDIF_NONAUDIO );
1131 			else
1132 				ClearFlags( DSP_FLAG_SPDIF_NONAUDIO );
1133 	}
1134 
1135 	//
1136 	// Mixer functions
1137 	//
1138 	virtual ECHOSTATUS SetNominalLevel( WORD wBus, BOOL bState );
1139 	virtual ECHOSTATUS GetNominalLevel( WORD wBus, PBYTE pbyState );
1140 
1141 	ECHOSTATUS SetAudioMonitor
1142 	(
1143 		WORD	wOutCh,
1144 		WORD	wInCh,
1145 		INT32	iGain,
1146 		BOOL 	fImmediate = TRUE
1147 	);
1148 
1149 	//
1150 	// SetBusOutGain - empty function on non-vmixer cards
1151 	//
1152 	virtual ECHOSTATUS SetBusOutGain(WORD wBusOut,INT32 iGain)
1153 	{
1154 		return ECHOSTATUS_OK;
1155 	}
1156 
1157 	// Send volume to DSP
1158 	ECHOSTATUS UpdateAudioOutLineLevel();
1159 
1160 	// Send vmixer volume to DSP
1161 	virtual ECHOSTATUS UpdateVmixerLevel();
1162 
1163 	virtual ECHOSTATUS SetPipeOutGain
1164 	(
1165 		WORD 	wPipeOut,
1166 		WORD 	wBusOut,
1167 		INT32	iGain,
1168 		BOOL 	fImmediate = TRUE
1169 	);
1170 
1171 	virtual ECHOSTATUS GetPipeOutGain
1172 	(
1173 		WORD 	wPipeOut,
1174 		WORD 	wBusOut,
1175 		INT32	&iGain
1176 	);
1177 
1178 	virtual ECHOSTATUS SetBusInGain
1179 	(
1180 		WORD 	wBusIn,
1181 		INT32 iGain
1182 	);
1183 
1184 	virtual ECHOSTATUS GetBusInGain( WORD wBusIn, INT32 &iGain);
1185 
1186 	//
1187 	//	See description of ECHOGALS_METERS above for
1188 	//	data format information.
1189 	//
1190 	virtual ECHOSTATUS GetAudioMeters
1191 	(
1192 		PECHOGALS_METERS	pMeters
1193 	);
1194 
1195 	ECHOSTATUS GetMetersOn
1196 	(
1197 		BOOL & bOn
1198 	)
1199 	{	bOn = ( 0 != m_wMeterOnCount ); return ECHOSTATUS_OK; }
1200 
1201 	ECHOSTATUS SetMetersOn( BOOL bOn );
1202 
1203 	//
1204 	//	Set/get Audio Format
1205 	//
1206 	ECHOSTATUS SetAudioFormat
1207 	(
1208 		WORD 							wPipeIndex,
1209 		PECHOGALS_AUDIOFORMAT	pFormat
1210 	);
1211 
1212 	ECHOSTATUS GetAudioFormat
1213 	(
1214 		WORD 							wPipeIndex,
1215 		PECHOGALS_AUDIOFORMAT	pFormat
1216 	);
1217 
1218 #ifdef MIDI_SUPPORT
1219 
1220 	//
1221 	//	MIDI output activity
1222 	//
1223 	virtual BOOL IsMidiOutActive();
1224 
1225 	//
1226 	// Set MIDI I/O on or off
1227 	//
1228 	ECHOSTATUS SetMidiOn( BOOL bOn );
1229 
1230 	//
1231 	// Read and write MIDI data
1232 	//
1233 	ECHOSTATUS WriteMidi
1234 	(
1235 		PBYTE		pData,
1236 		DWORD		dwLength,
1237 		PDWORD	pdwActualCt
1238 	);
1239 
1240 	ECHOSTATUS ReadMidi
1241 	(
1242 		WORD 		wIndex,				// Buffer index
1243 		DWORD &	dwData				// Return data
1244 	);
1245 
1246 #endif // MIDI_SUPPORT
1247 
1248 	//
1249 	//	Reset the DSP and load new firmware.
1250 	//
1251 	virtual ECHOSTATUS LoadFirmware();
1252 
1253 	//
1254 	// Put the hardware to sleep
1255 	//
1256 	virtual ECHOSTATUS GoComatose();
1257 
1258 
1259 #ifdef DIGITAL_INPUT_AUTO_MUTE_SUPPORT
1260 	//
1261 	// Get and set the digital input auto-mute flag
1262 	//
1263 	virtual ECHOSTATUS GetDigitalInputAutoMute(BOOL &fAutoMute);
1264 	virtual ECHOSTATUS SetDigitalInputAutoMute(BOOL fAutoMute);
1265 
1266 #endif // DIGITAL_INPUT_AUTO_MUTE_SUPPORT
1267 
1268 #ifdef SUPERMIX
1269 	//
1270 	// Set the input gain boost
1271 	//
1272 	virtual ECHOSTATUS SetInputGainBoost(WORD wBusIn,BYTE bBoostDb)
1273 	{ return ECHOSTATUS_NOT_SUPPORTED; }
1274 #endif
1275 
1276 };		// class CDspCommObject
1277 
1278 typedef CDspCommObject * PCDspCommObject;
1279 
1280 #ifdef _WIN32
1281 #pragma pack( pop )
1282 #endif
1283 
1284 #endif
1285 
1286 // **** DspCommObject.h ****
1287