1 
2 /*
3  *  Diverse SLab audio routines.
4  *  Copyright (c) by Nick Copeland <nickycopeland@hotmail.com> 1996,2012
5  *
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 3 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 
23 #ifndef SLAB_DEVS
24 #define SLAB_DEVS
25 
26 #include "slabrevisions.h"
27 #include "slabdefinitions.h"
28 #include "slabtrack.h"
29 #include "slabmixer.h"
30 
31 #if (BRISTOL_HAS_ALSA == 1)
32 #include "slabalsadev.h"
33 #endif
34 
35 /* ALSA has the value 0x04 */
36 #ifdef BRISTOL_PA
37 #ifndef AUDIO_PULSE
38 #define AUDIO_PULSE 0x10
39 #endif
40 
41 /*
42  * These make up the threaded interface, the Interface call never returns, it
43  * calls the audio shim with each buffer of data.
44  */
45 extern int bristolPulseClose();
46 extern int bristolPulseInterface();
47 
48 /*
49  * And these are the simple interface, this sits underneath libbristolaudio so
50  * has the same interface as ALSA and OSS. The devRead() call is actually null,
51  * it just zeros the buffer and continues.
52  */
53 extern int pulseDevOpen();
54 extern int pulseDevClose();
55 extern int pulseDevRead();
56 extern int pulseDevWrite();
57 #endif
58 
59 /*
60  * I want these out of the compilation
61 #include <sys/types.h>
62 
63 #ifdef SLAB_MIDI_SYNC
64 #include <sys/time.h>
65 #endif
66  */
67 
68 #include <stdio.h>
69 
70 #define SYNC_SAMPLES 21
71 
72 #define DEV_NAME_LEN	128
73 #define ALGO_COUNT		16
74 
75 #define	SLAB_RDONLY			11 /* 0xB */
76 #define SLAB_WRONLY			12 /* 0xC */
77 #define SLAB_FULL_DUPLEX	13 /* 0xD */
78 #define SLAB_HALF_DUPLEX	14 /* 0xE */
79 #define SLAB_HOLD			15 /* 0xF */
80 #define SLAB_FLAG_MASK		0x000f
81 
82 #define SLAB_NO_CONTROLS	0x0010 /* prevent /dev/audio or /dev/audioctl ioctl */
83 /* SB_DUPLEX has taken the 0x20 flag position */
84 #define SLAB_8_BIT_IN		0x0040 /* For general convergence options */
85 #define SLAB_8_BIT_OUT		0x0080 /* For general convergence options */
86 #ifdef SUBFRAGMENT
87 #define SLAB_SUBFRAGMENT	0x0100 /* decouple blockSampleSize from fragemnts */
88 #define SLAB_SUBF_IOCTL		0x2000 /* Allow subfragment to use old ioctl()s */
89 #endif
90 #ifdef IOCTL_DBG
91 #define SLAB_AUDIODBG	0x0200 /* For ioctl() debug info */
92 #endif
93 #define SLAB_FDUP		0x0400
94 #define SLAB_AUDIODBG2	0x80000000 /* For verbose debug info */
95 
96 #ifdef SB_ONR
97 #define SLAB_NO_ONR	1
98 #define SLAB_1_BIT_ONR	2
99 #define SLAB_2_BIT_ONR	3
100 #define SLAB_3_BIT_ONR	4
101 #define SLAB_MAX_ONR	4
102 #endif
103 
104 #ifdef METRONOME
105 #define INPUT_ADJUST	/* Retiming of input signal for synchronisation */
106 #define METRO_RECORD 0x40
107 #define METRO_MIN 100
108 #endif
109 
110 /*
111  * These should be MIX_C_GO_???
112  */
113 #define ADIOD_INPUT			11
114 #define ADIOD_OUTPUT		12
115 #define ADIOD_DUPLEX		13
116 
117 /*
118  * structure definition made here, this is arrayed into the controlBuffer, one
119  * entry per device supported, currently 8.
120  */
121 typedef struct DuplexDev {
122 	int PID;			/* Analogue/Digital Input/Output Daemon */
123 	int devID;			/* This device identifier index */
124 	int BufferKey;		/* SHMEM Key */
125 	int samplecount;
126 	char *IBuffer;		/* analogue input buffer */
127 	int IBufferSize;	/* analogue output buffer size */
128 	int IBufferID;
129 	int ISegmentSize;	/* size of analogue output segments */
130 	char *OBuffer;		/* analogue output buffer */
131 	int OBufferSize;	/* analogue output buffer size */
132 	int OBufferID;
133 	int OSegmentSize;	/* size of analogue output segments */
134 	int OWorkSpaceSize;	/* For output fragmentation */
135 	/*
136 	 * PWrite is for mixengined to adiod. CRead is for adiod from mixengined
137 	 * to audio device.
138 	 */
139 	int PWriteBytes;	/* how much data written to buffer by parent */
140 	int CWriteBytes;	/* how much data written to device by adiod */
141 	char *PWrite;		/* where the engine is currently mixed to */
142 	char *CRead;		/* from where the adiod process is audio outing */
143 #ifdef FLOAT_SYNC_FIX
144 	char *mainPWrite;	/* Where the main mix is, regarding bus return mix */
145 	int mainPWriteBytes;	/* Counter of where the main mix is */
146 #endif
147 	int UnderRunCount;	/* Parent cannot provide data in time for write */
148 	/*
149 	 * CWrite is adiod into diskBuffer. PRead is mixiod into disk data file.
150 	 * The window mechanism of Bytes count is used to allow mixiod to determine
151 	 * how much data from this adiod can be synchronised to disk.
152 	 */
153 	int CReadBytes;		/* how much data read from device by adiod */
154 	int PReadBytes;		/* how much data read from buffer by mixiod */
155 	int realReadBytes;	/* how much data really read from device by adiod */
156 	char *PRead;		/* where the data is currently saved from */
157 	char *CWrite;		/* where the adiod process is audio inning */
158 	int OverRunCount;	/* Parent cannot clear out read audio data */
159 	int recordOffset1;
160 	int recordOffset2;
161 	int track1;
162 	int track2;
163 	int fd;				/* output process file descriptor */
164 	int fd2;			/* input process file descriptor */
165 	int mixerFD;		/* mixer device file descriptor */
166 	mixAlgo inputAlgorithm[ALGO_COUNT];
167 	mixAlgo outputAlgorithm[ALGO_COUNT];
168 	char devName[DEV_NAME_LEN];	/* output process file name */
169 	char mixerName[DEV_NAME_LEN];	/* mixer file name */
170 	int stereoCaps;
171 	int monoCaps;
172 	int recordCaps;
173 	int genCaps;
174 	int	cflags; 		/* configured RDONLY, WRONLY, HALF/FULL_DUPLEX */
175 	int	flags; 			/* active RDONLY, WRONLY, HALF_DUPLEX, FULL_DUPLEX */
176 	int readSampleRate;	/* For the physical device */
177 	int writeSampleRate;/* For the physical device */
178 	int channels;
179 	/*
180 	 * for altering analogue device parameters (4Front OSS stuff).
181 	 */
182 	int paramID;
183 	short paramValueLeft;
184 	short paramValueRight;
185 	int Command;		/* output operation to be executed */
186 	int OpState;	/* output operation to be executed */
187 	int status;			/* adiod operational status */
188 	unsigned long SleepPeriod;
189 	int inputLMax;
190 	int inputLAve;
191 	int inputRMax;
192 	int inputRAve;
193 	int outputLMax;
194 	int outputLAve;
195 	int outputRMax;
196 	int outputRAve;
197 	short d1;
198 	short d2;
199 #ifdef METRONOME
200 #ifdef INPUT_ADJUST
201 	int inIndex;	/* Will be used to determine current read slippage */
202 	int outIndex;	/* Will be used to determine current read index */
203 	int inAdjust;	/* Defines the number of samples to slip on input */
204 #endif
205 #endif
206 #ifdef SUBFRAGMENT
207 	int fragSize;
208 	int fragIndexSave;
209 	int fragOutIndexSave;
210 	char *fragBuf;
211 #endif
212 #ifdef ADIOD_MULTI
213 	int skipCount;
214 	int skipFlag;
215 #endif
216 #ifdef I_NR
217 	/*
218 	 * Input noise reduction params
219 	 */
220 	trackparams inRp[2];
221 #endif
222 	int preLoad;
223 #ifdef FLOAT_PROC
224 	int masterFloatAlgoLeft[MAX_DEVICES]; /* MAXDEVS is incorrent, there is */
225 	int masterFloatAlgoRight[MAX_DEVICES];/* relationship, it is just a count */
226 #endif
227 #ifdef DELTA_ACC /* For delta accumulation with microAdjust code */
228 	int lDeltaOut;
229 	int rDeltaOut;
230 	int lOldOut;
231 	int rOldOut;
232 	int lDeltaIn;
233 	int rDeltaIn;
234 	int lOldIn;
235 	int rOldIn;
236 #endif
237 #ifdef SLAB_MIDI_SYNC
238 	/*
239 	 * Note that we are going to rely on read rates. Also, these who structures
240 	 * should be moved into a separate header file in the libslabaudio space to
241 	 * remove dependencies on the diverse system header files.
242 	 */
243 	struct {long int tv_sec, tv_usec;} startTime;
244 	struct {long int tv_sec, tv_usec;} timeLastRead;
245 	int deltaReadSamples;
246 	float estReadRate;
247 	int syncPreLoad; /* 10 */
248 	int syncBias; /* 1500 */
249 	int syncHoldDown; /* 55 */
250 	int syncAdjust; /* 100 */
251 	int syncStability; /* internal factor */
252 #endif
253 #ifdef SLAB_NET_TAP
254 	/*
255 	 * Use device name length since it is already defined.
256 	 */
257 	char hostname[DEV_NAME_LEN];
258 	int port;
259 	int direction;
260 	int netfd;
261 #endif
262 #ifdef SOFT_START
263 	int crossFade;
264 #endif
265 #ifdef MICROADJUST
266 	/*
267 	 * These are used for per device microAdjustments, which will be used to
268 	 * sync devices.
269 	 */
270 	int microAdjust; /* This will be a sum of microAdjust and sync */
271 	int microSyncAdjust; /* This is just the sync factor */
272 	int microCurrentOut;
273 	int microCurrentIn;
274 #endif
275 #ifdef SECONDARY_FLAGS
276 	/*
277 	 * Intrusive flags, if changed, need an engine restart.
278 	 */
279 	int	sflags; /* secondary flags, some used (3.20) */
280 	int	siflags; /* secondary intrusive flags, some used (3.20) */
281 	int	tflags; /* tertiary flags (not used at the moment (3.20) */
282 	int	tiflags; /* tertiary  intrusiveflags (not used at the moment (3.20) */
283 #endif
284 	/*
285 	 * Keep a number of sample times.
286 	 */
287 	float sduration;
288 	struct {long int tv_sec, tv_usec;} realTimes[SYNC_SAMPLES];
289 	int syncIndex;
290 	float estimate;
291 } duplexDev;
292 
293 #ifndef MONO_CAPABILITIES
294 #define MONO_CAPABILITIES(x) audioDev->monoCaps
295 #define STEREO_CAPABILITIES(x) audioDev->stereoCaps
296 #define ALL_CAPABILITIES(x) (audioDev->stereoCaps | audioDev->monoCaps)
297 #define ALL_DEV2_CAPABILITIES (audioDev->stereoCaps | audioDev->monoCaps)
298 #endif
299 
300 #endif /* SLAB_DEVS */
301