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
147Setting the sample rates on Layla24 is somewhat schizophrenic.
148
149For standard rates, it works exactly like Mona and Gina24.  That is, for
1508, 11.025, 16, 22.05, 32, 44.1, 48, 88.2, and 96 kHz, you just set the
151appropriate bits in the control register and write the control register.
152
153In order to support MIDI time code sync (and possibly SMPTE LTC sync in
154the future), Layla24 also has "continuous sample rate mode".  In this mode,
155Layla24 can generate any sample rate between 25 and 50 kHz inclusive, or
15650 to 100 kHz inclusive for double speed mode.
157
158To 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
170frequency_reg = (LAYLA24_MAGIC_NUMBER / sample_rate) - 2
171
172Note 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
178Once you have set the control register up for continuous mode, you can just
179write the frequency register to change the sample rate.  This could be
180used for MIDI time code sync. For MTC sync, the control register is set for
181continuous mode.  The driver then just keeps writing the
182SET_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
564typedef 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
634class CDspCommObject
635{
636protected:
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
688protected :
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
787public:
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
1278typedef CDspCommObject * PCDspCommObject;
1279
1280#ifdef _WIN32
1281#pragma pack( pop )
1282#endif
1283
1284#endif
1285
1286// **** DspCommObject.h ****
1287