2
DB Fourier Synthesis Daemon
3
===========================
7
This deamon creates input "channels" using pipes and network sockets,
8
and then combines their input for writing to /dev/dsp.
10
The daemon assumes that the data is 16 bit 44.1 kHz stereo. It *is*not*
11
the task of this daemon to perform audio format conversions. Such
12
calculation would add delay to channels that do not require it.
14
The number of pipe channels is a constant number set at startup. Due to
15
connection oriented nature of socket streams, the number of socket channels
16
in existence at any given time is variable. The maximum number of
17
connections is also set at startup.
19
This software is brought to you by the letter A and the number 4
21
Version: see VRESION_STR declared below
23
Copyright (c) 1999, 2000
26
This program is free software; you can redistribute it and/or modify
27
it under the terms of the GNU General Public Licensse as published by
28
the Free Software Foundation; either version 2 of the License, or
29
(at your option) any later version.
31
This program is distributed in the hope that it will be useful,
32
but WITHOUT ANY WARRANTY; without even the implied warranty of
33
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34
GNU General Public License for more details.
36
You should have received a copy of the GNU General Public License
37
along with this program; if not, write to the Free Software
38
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44
source code used to write wave files copied from the
45
XMMS Disk Writer Plugin, released under the GNU General Public License
46
Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas,
47
Thomas Nilsson and 4Front Technologies
56
SIGHUP - close and reopen audio devices
57
SIGUSR1 - start recording to disk using filename stored in sysdata structure
58
(filled in by dbmixer).
59
SIGUSR2 - stop recording to disk.
73
#include <sys/ioctl.h>
74
#include <sys/types.h>
82
#include <dbsoundcard.h>
85
#include <dbchannel.h>
90
#define DBFSD_VERSION_STR "A.12"
92
/* timeout values for the select call. */
93
#define MIN_TIMEOUT_VALUE_SEC 0
94
#define MAX_TIMEOUT_VALUE_SEC 60
95
#define MIN_TIMEOUT_VALUE_USEC 25000
96
#define MAX_TIMEOUT_VALUE_USEC 0
98
/* local global variables */
100
extern int debug_level;
102
/* local prototypes */
103
void shutdown_dbfsd();
105
/***************************************************************************/
106
/* Global variables */
107
/***************************************************************************/
109
/* daemon system data*/
110
dbfsd_data * sysdata;
112
int loop_flag; /*main loop flag*/
113
int free_channels_flag;
115
int single_output_flag;
116
int reset_audio_flag;
118
int shmid; /* shared memory id for channels*/
119
int sysshmid; /* shared memory id for dbfsd_data*/
120
int semid; /* channel semaphore id */
127
local_channel *local_channels, *cue_channels;
128
/* socket_channel **socket_channels; */
130
char tempdirstr[512], cue_tempdirstr[512];
132
/*flags to hold cmdline switches*/
136
fd_set read_ch_set; /*fd set for select*/
138
signed short output_buf[DB_BUFSIZE_SHORT], cue_output_buf[DB_BUFSIZE_SHORT], empty_buf[DB_BUFSIZE_SHORT];
140
/* signed short *output_buf, *cue_output_buf, *empty_buf; */
142
oss_control_struct * main_audio, * cue_audio;
144
/***************************************************************************/
145
/* Initialization functions */
146
/***************************************************************************/
149
print_version - outputs version info to stdout
153
printf("DB Fourier Synthesis Daemon for OSS\n");
154
printf("%s\n",DBMIX_COPYRIGHT);
155
printf("DBfsd Version: %s\n",DBFSD_VERSION_STR);
156
printf("DBMix Version: %s\n",DBMIX_VERSION);
160
print_greeting - outputs to stdout a greeting
170
printf("Supported options (argument type in parens) [defaults in brackets]: \n");
171
printf(" -d turn on debug messages to console (none) [Off] \n");
172
printf(" -c set op mode to cue (none) [no cue] \n");
173
printf(" -e output cue as left channel of master out (none) [Off] \n");
174
printf(" -n set total number of input channels (int) [4] \n");
175
printf(" -s set number of input channels to be sockets (int) [0] \n");
176
printf(" -a set master output audio device (string) [/dev/dsp0]\n");
177
printf(" -b set cue output audio device (string) [/dev/dsp2]\n");
178
printf(" -r set number of OSS output fragments (int) [128] \n");
179
printf(" -o write mixed output to stdout (none) [Off] \n");
180
printf(" -v print version information (none) \n");
181
printf(" -h print this message (none) \n");
183
printf("For example, to run the server with cueing, 5 input channels, and sending\n");
184
printf("master output to /dev/dsp15 you would type:\n");
185
printf("dbfsd -c -n 5 -a /dev/dsp15\n");
187
printf("WARNING: if you use the -r option, the minimum number of allowable fragments\n");
188
printf(" is %d. Any fewer, and audio corruption may occur withing the driver.\n",DB_MIN_AUDIO_BUFFS);
189
printf(" Depending on your system, if you expeience audio corruption, \n");
190
printf(" you should increase the number of fragments.\n");
197
parse_cmdline - steps through argv and sets all the variables
200
outputs - sets system variables
202
void parse_cmdline(int argc, char* argv[])
206
/* init arguments... */
210
single_output_flag = FALSE;
214
sprintf(tempdirstr,"/tmp/ch");
215
sysdata->cue_audio_device[0] = '\0';
216
cue_tempdirstr[0] = '\0';
218
sysdata->pid = getpid();
219
strcpy(sysdata->main_audio_device,DEFAULT_AUDIO_DEVICE);
222
while ((opt = getopt(argc,argv,"n:s:a:b:ovqhdcer:")) != -1)
231
strcpy(sysdata->main_audio_device,optarg);
232
Debug("Set master audio device to be: \"%s\"",sysdata->main_audio_device);
235
strcpy(sysdata->cue_audio_device,optarg);
236
Debug("Set cue audio device to be: \"%s\"",sysdata->cue_audio_device);
239
Debug("Set single output flag.");
240
single_output_flag = TRUE;
241
sysdata->single_output = TRUE;
242
sysdata->cue_split = TRUE;
243
/* fail through to enable cue */
246
sysdata->cue_enabled = TRUE;
247
Debug("set cue flag.");
253
sysdata->num_channels = atoi(optarg);
254
printf("sysdata->num_channels set %d\n",sysdata->num_channels);
258
Debug("output to stdout");
260
case 'q': /* I wish I could remember what this was for... */
262
Debug("quiet flag set");
265
sysdata->num_main_buffs = atoi(optarg);
267
if (sysdata->num_main_buffs < DB_MIN_AUDIO_BUFFS)
269
printf("The requested number of audio buffs is less than the allowable minimum. Setting the number of buffs to be the minimum of: %d buffers.",DB_MIN_AUDIO_BUFFS);
270
sysdata->num_main_buffs = DB_MIN_AUDIO_BUFFS;
273
sysdata->num_cue_buffs = sysdata->num_main_buffs;
274
Debug("num audio buffs set %d\n",sysdata->num_main_buffs);
276
sysdata->num_sockets = atoi(optarg);
277
Debug("numsockets set %d\n",sysdata->num_sockets);
280
sysdata->debug_level = debug_level = 1;
281
Debug("debug level set\n");
284
printf("option needs a value\n");
287
printf("unknown option: %c\n",optopt);
296
sprintf(cue_tempdirstr,"/tmp/cue");
298
if (sysdata->cue_audio_device[0] == '\0')
300
strcpy(sysdata->cue_audio_device,DEFAULT_CUE_AUDIO_DEVICE);
303
sysdata->cue_pid = getpid();
311
init_sysdata - allocates shared memory to hold the system dbfsd_data struct
315
side effects - allocates a chunk of shared memory and point to it with sysdata
319
/*allocate ssytem data struct*/
320
sysshmid = shmget((key_t) DB_SYSTEM_SM_KEY, sizeof(dbfsd_data),
321
0666 | O_RDWR | IPC_CREAT);
325
Error("init_sysdata: error creating shared memory for system data.");
330
sysdata = shmat(sysshmid,(void *)0, 0);
332
if ((int)sysdata == -1)
334
Error("init_sysdata: error attaching system data shared memory.");
336
if (shmdt(sysdata) == -1)
338
Error("init_sysdata: could not detach system data memory segment.");
341
if (shmctl(sysshmid,IPC_RMID, 0) == -1)
343
Error("init_sysdata: could not delete system data shared memory segment.");
349
Debug("init_sysdata: system data shared memory attached successfully.");
351
memset(sysdata->filename,0,FILENAME_MAX);
353
sysdata->num_channels = 4;
354
sysdata->num_sockets = 0;
355
sysdata->debug_level = 0;
356
sysdata->ready_count = 0;
357
sysdata->free_channel_index = 0;
358
sysdata->clipping_threshold = 20;
359
sysdata->main_audio_device[0] = '\0';
360
sysdata->cue_audio_device[0] = '\0';
361
sysdata->main_mixer_device[0] = '\0';
362
sysdata->cue_mixer_device[0] = '\0';
363
sysdata->clipping = 0;
364
sysdata->num_main_buffs = DB_NUM_FRAGMENTS;
365
sysdata->num_cue_buffs = DB_NUM_FRAGMENTS;
366
sysdata->left_balance = 100;
367
sysdata->right_balance = 100;
368
sysdata->cue_split = 0;
369
sysdata->single_output = 0;
370
sysdata->talkover_enabled = 0;
371
sysdata->skip_max = DEFAULT_SKIP_MAX;
372
sysdata->default_sampler_time = DB_SAMPLER_DEFAULT_TIME;
373
sysdata->mixer_pid = 0;
374
sysdata->sampler_op_flag = 0;
375
sysdata->recording = 0;
380
int reset_channel(local_channel * ch, int reset)
386
Debug("Reseting channel %d...",ch->index);
387
Debug(" Closing and unlinking pipes...");
389
close(ch->server_comm_fd);
390
unlink(ch->comm_filename);
391
close(ch->server_cue_fd);
392
unlink(ch->cue_filename);
394
Debug(" closing message queue...");
396
if (msgctl(ch->msg_q_id,IPC_RMID,0) != SUCCESS)
398
Error("Failed to delete message queue on channel %d",ch->index);
403
Debug(" Creating channel %d...",ch->index);
406
/* intialize the channel name to "Channel x" */
407
sprintf(ch->channel_name,"Channel - %d",ch->index+1);
409
Debug(" Set channel name to: %s",ch->channel_name);
411
/* create message queue */
412
ch->msg_q_id = msgget(DB_CHANNELS_Q_KEY_BASE + ch->index, 0666 | IPC_CREAT);
414
if (ch->msg_q_id == -1)
416
Error("Failed to create message queue on channel %d",ch->index);
419
Debug(" reset_channel: Opened message queue.");
421
/* create comm pipe */
422
if (mkfifo(ch->comm_filename,0777) != 0)
426
sprintf(tempstr,"reset_channel: Error creating %s",ch->comm_filename);
427
perror(tempstr); return FAILURE;
432
if ((ch->server_comm_fd = open(ch->comm_filename,
433
O_RDONLY | O_NONBLOCK )) == -1)
435
sprintf(tempstr,"reset_channel: Error opening %s for read:",ch->comm_filename);
440
Debug(" reset_channel: opened pipe %s",ch->comm_filename);
444
/* create cue pipe */
445
Debug(" reset_channel: creating cue pipe...");
447
if (mkfifo(ch->cue_filename,0777) != 0)
451
sprintf(tempstr,"reset_channel: Error creating %s",
459
Debug(" reset_channel: Opening cue pipe...");
460
if ((ch->server_cue_fd = open(ch->cue_filename,O_RDONLY | O_NONBLOCK )) == -1)
462
sprintf(tempstr,"reset_channel: Error opening %s for read:",
468
ch->channel_flags |= CUE_FLAG;
470
Debug(" reset_channel: opened pipe %s",ch->cue_filename);
474
ch->channel_flags &= ~CUE_FLAG;
475
ch->cue_filename[0] = '\0';
476
ch->server_cue_fd = -1;
479
/*add to select set*/
480
FD_SET(ch->server_comm_fd,&read_ch_set);
483
ch->free_channel = TRUE;
484
ch->is_symlink = FALSE;
485
ch->left_gain = DEFAULT_GAIN;
486
ch->right_gain = DEFAULT_GAIN;
487
ch->cue_left_gain = DEFAULT_GAIN;
488
ch->cue_right_gain = DEFAULT_GAIN;
490
ch->base_pitch = DEFAULT_PITCH;
491
ch->user_pitch = DEFAULT_PITCH;
492
ch->message_handler = NULL;
499
/* init sampler variables */
500
ch->sampler_state = SAMPLER_OFF;
501
ch->sampler_time = sysdata->default_sampler_time;
502
ch->sampler_bufsize = 0;
503
ch->sampler_size = 0;
504
ch->sampler_readoffset = 0;
505
ch->sampler_startoffset = 0;
506
ch->sampler_endoffset = 0;
507
ch->sampler_buf = NULL;
509
/* init default channel flags */
510
ch->channel_flags |= (PITCH_FLAG | PAUSE_FLAG);
512
Debug(" reset_channel: channel %d reset.",ch->index);
519
* init_channels - creates and initializes the input channels
520
* channels 1 2 and 3 are named pipes.
521
* channel 4 is the soundcard linein.
523
* inputs: str - filesystem location for FIFO's
524
* num - number of channels
525
* outputs: error codes...
530
local_channel* temp_ch;
533
len = strlen(tempdirstr) + 20;
535
/* output_buf = (signed short*) malloc(DB_BUFSIZE_CHAR); */
536
/* cue_output_buf = (signed short*) malloc(DB_BUFSIZE_CHAR); */
537
/* empty_buf = (signed short *) malloc(DB_BUFSIZE_CHAR); */
539
memset(empty_buf,0,DB_BUFSIZE_CHAR);
541
channels_key = DB_CHANNELS_SM_KEY;
543
Debug("init_channels: samples per channel buffer %d",DB_BUFSIZE_SHORT);
545
/* allocate input channel control structs */
546
shmid = shmget(channels_key, ((sysdata->num_channels) * sizeof(local_channel)), 0666 | O_RDWR | IPC_CREAT);
550
Error("init_channels: error creating shared memory.");
555
local_channels = shmat(shmid,(void *)0, 0);
557
if ((int)local_channels == -1)
559
Error("init_channels: error attaching shared memory.");
561
if (shmdt(local_channels) == -1)
563
Error("init_channels: could not detach memory segment.");
566
if (shmctl(shmid,IPC_RMID, 0) == -1)
568
Error("init_channels: could not delete shared memory segment.");
574
Debug("init_channels: shared memory attached successfully.");
576
FD_ZERO(&read_ch_set);
578
temp_ch = local_channels;
580
/*initialize channels*/
581
for (i = 0; i < sysdata->num_channels; i++)
583
local_channels[i].channel_flags = 0;
585
/*create comm pipe filename*/
586
sprintf(local_channels[i].comm_filename,"%s%d_comm",tempdirstr,i+1);
587
/*create cue filename*/
590
sprintf(local_channels[i].cue_filename,"%s%d_cue",tempdirstr,i+1);
594
local_channels[i].cue_filename[0] = '\0';
597
local_channels[i].index = i;
598
reset_channel(temp_ch,FALSE);
607
sigexit - changes system variables to force clean shutdown
611
void sigexit(int signum)
614
Debug("Sigexit has been called.");
618
void sigcont(int signum)
620
Debug("Sigcont has been called.");
625
sighup - callback when a SIGHUP signal is recieved, resets audio devices
627
void sighup(int signum)
629
Debug("sighup has been called.");
631
reset_audio_flag = 1;
636
sigusr - callback when a SIGUSR signal is recieved, starts recording to disk.
638
void sigusr1(int signum)
640
Debug("sigusr1 has been called.");
642
/* if not recording, start recording */
643
if (record_fid == NULL)
645
sysdata->recording = 1;
648
record_fid = fopen(sysdata->filename,"wb");
652
Error("DBFSD: Could not open output file for recording.\n");
656
/* initialize wav header */
657
memcpy(&header.main_chunk, "RIFF", 4);
658
header.length = GUINT32_TO_LE(0);
659
memcpy(&header.chunk_type, "WAVE", 4);
660
memcpy(&header.sub_chunk, "fmt ", 4);
661
header.sc_len = GUINT32_TO_LE(16);
662
header.format = GUINT16_TO_LE(1);
663
header.modus = GUINT16_TO_LE(DB_CHANNEL_NUM_CHANNELS);
664
header.sample_fq = GUINT32_TO_LE(DB_SAMPLE_RATE);
665
header.bit_p_spl = GUINT16_TO_LE(DB_SAMPLE_SIZE * 8);
666
header.byte_p_sec = GUINT32_TO_LE(DB_SAMPLE_RATE * DB_CHANNEL_NUM_CHANNELS * DB_SAMPLE_SIZE);
667
header.byte_p_spl = GUINT16_TO_LE((GUINT16_FROM_LE(header.bit_p_spl) / (8 / DB_CHANNEL_NUM_CHANNELS)));
668
memcpy(&header.data_chunk, "data", 4);
669
header.data_length = GUINT32_TO_LE(0);
671
/* init data count to zero */
674
/* write wav header */
675
fwrite(&header, sizeof(wav_header), 1, record_fid);
681
sigusr2 - callback for SIGUSR2 signal, stops recording to disk
683
void sigusr2(int signum)
685
Debug("sigusr2 has been called");
687
if (record_fid != NULL)
689
sysdata->recording = 0;
691
/* recording, stop recording */
692
header.length = GUINT32_TO_LE(record_count + sizeof(wav_header) - 8);
693
header.data_length = GUINT32_TO_LE(record_count);
695
fseek(record_fid, 0, SEEK_SET);
696
fwrite(&header, sizeof(wav_header), 1, record_fid);
706
shutdown - frees all resources before exiting.
708
No need to free the global malloc'd bits here since the system process
709
cleanup will take care of it...
714
void shutdown_dbfsd()
720
Debug("removing channels:");
724
if(local_channels != NULL)
726
for (i = 0; i < sysdata->num_channels;i++)
728
Debug(" removing channel %d of %d...",i+1,sysdata->num_channels);
729
close(local_channels[i].server_comm_fd);
730
close(local_channels[i].server_cue_fd);
731
unlink(local_channels[i].comm_filename);
732
unlink(local_channels[i].cue_filename);
733
if (msgctl(local_channels[i].msg_q_id,IPC_RMID,0) == -1)
735
Error("shutdown_dbfsd: could not delete message queue.");
739
Debug("deleteing shared memory segment for channel data... ");
741
if (shmdt(local_channels) == -1)
743
Error("shutdown_dbfsd: could not detach memory segment.");
746
if (shmctl(shmid,IPC_RMID, 0) == -1)
748
Error("shutdown_dbfsd: could not delete shared memory segment.");
752
Debug("deleteing system data shared memory segment... ");
754
if (shmdt(sysdata) == -1)
756
Error("shutdown_dbfsd: could not detach system data memory segment.");
759
if (shmctl(sysshmid,IPC_RMID, 0) == -1)
761
Error("shutdown_dbfsd: could not delete system data shared memory segment.");
764
Debug("closing audio devices...");
766
close_audio(cue_audio);
767
close_audio(main_audio);
769
Debug("done.\nthank you for using DBfsd.");
770
/*I can never remember if this should be a 0 or a 1...*/
776
/*************************************************************************/
777
/* Execution functions */
778
/*************************************************************************/
784
Loops through the available looking for a channel that is not in use.
785
If one is found, a link to /tmp/ch otherwise /tmp/ch does not exist.
786
When complete, ch_link is the index of the linked channel, otherwise
787
is is greater than data->num_channels.
790
void make_ch_symlink()
796
/*find first unused channel*/
801
while ((i < sysdata->num_channels) && notdone)
803
if (local_channels[i].free_channel)
805
symlink(local_channels[i].comm_filename,tempdirstr);
806
local_channels[i].is_symlink = TRUE;
809
sysdata->free_channel_index = i;
817
Debug("MAKE_SYMLINK: made link to channel %d",i);
821
sysdata->free_channel_index = -1;
822
free_channels_flag = FALSE;
823
Debug("MAKE_SYMLINK: All channels are in use.");
828
/* run_it debug functions */
829
void PrintData(char* str)
831
Debug("%s ready_count: %d free_channel_index: %d",str,
832
sysdata->ready_count,sysdata->free_channel_index);
836
void PrintChannelSettings(local_channel * ch)
838
printf("====================\n");
839
printf("Current Channel Settings:\n");
840
printf(" Comm Name: %s\n",ch->comm_filename);
842
if ((ch->channel_flags & CUE_FLAG) == CUE_FLAG)
843
printf(" Cue Name: %s\n",ch->cue_filename);
845
switch (ch->channel_type)
847
case PIPE_CHANNEL: printf(" Type: PIPE\n");break;
848
case SOCKET_CHANNEL: printf(" Type: SOCKET\n");break;
849
default: printf(" Type: UNKNOWN\n");
854
case 0: printf(" Cue? NO\n"); break;
855
default: printf(" Cue? YES\n"); break;
858
switch (ch->free_channel)
860
case 0: printf(" Free? NO\n"); break;
861
default: printf(" Free? YES\n"); break;
864
switch (ch->is_symlink)
866
case 0: printf(" Symlink? NO\n"); break;
867
default: printf(" Symlink? YES\n");
870
printf(" Left Gain: %d\n",ch->left_gain);
871
printf(" Right Gain: %d\n",ch->right_gain);
873
printf("====================\n");
877
signed short * add_main_audio(signed short * out_buf,local_channel ** buf_pointers,
880
switch (channel_count)
884
memcpy(out_buf,buf_pointers[0]->buffer.buf,DB_BUFSIZE_CHAR);
888
fs_add2channels(out_buf,&(buf_pointers[0]->buffer),
889
&(buf_pointers[1]->buffer));
893
fs_add3channels(out_buf,&(buf_pointers[0]->buffer),
894
&(buf_pointers[1]->buffer),&(buf_pointers[2]->buffer));
898
fs_add4channels(out_buf, &(buf_pointers[0]->buffer),
899
&(buf_pointers[1]->buffer), &(buf_pointers[2]->buffer),
900
&(buf_pointers[3]->buffer));
904
fs_add5channels(out_buf, &(buf_pointers[0]->buffer),
905
&(buf_pointers[1]->buffer), &(buf_pointers[2]->buffer),
906
&(buf_pointers[3]->buffer), &(buf_pointers[4]->buffer));
910
fs_add6channels(out_buf, &(buf_pointers[0]->buffer),
911
&(buf_pointers[1]->buffer), &(buf_pointers[2]->buffer),
912
&(buf_pointers[3]->buffer), &(buf_pointers[4]->buffer),
913
&(buf_pointers[5]->buffer));
917
fs_add7channels(out_buf, &(buf_pointers[0]->buffer),
918
&(buf_pointers[1]->buffer), &(buf_pointers[2]->buffer),
919
&(buf_pointers[3]->buffer), &(buf_pointers[4]->buffer),
920
&(buf_pointers[5]->buffer), &(buf_pointers[6]->buffer));
924
fs_add8channels(out_buf, &(buf_pointers[0]->buffer),
925
&(buf_pointers[1]->buffer), &(buf_pointers[2]->buffer),
926
&(buf_pointers[3]->buffer), &(buf_pointers[4]->buffer),
927
&(buf_pointers[5]->buffer), &(buf_pointers[6]->buffer),
928
&(buf_pointers[7]->buffer));
932
Error("add_main_audio: fs_addNchannels NOT IMPLEMENTED!!!!!!!!");
933
/* fs_addNchannels(out_buf,&(buf_pointers,sysdata->num_channels);*/
942
signed short * add_cue_audio(signed short * out_buf,local_channel ** buf_pointers,
945
switch (channel_count)
949
memcpy(out_buf,buf_pointers[0]->cue_buffer.buf,DB_BUFSIZE_CHAR);
953
fs_add2channels(out_buf,
954
&(buf_pointers[0]->cue_buffer),
955
&(buf_pointers[1]->cue_buffer));
959
fs_add3channels(out_buf,&(buf_pointers[0]->cue_buffer),
960
&(buf_pointers[1]->cue_buffer),&(buf_pointers[2]->cue_buffer));
964
fs_add4channels(out_buf, &(buf_pointers[0]->cue_buffer),
965
&(buf_pointers[1]->cue_buffer), &(buf_pointers[2]->cue_buffer),
966
&(buf_pointers[3]->cue_buffer));
970
fs_add5channels(out_buf, &(buf_pointers[0]->cue_buffer),
971
&(buf_pointers[1]->cue_buffer), &(buf_pointers[2]->cue_buffer),
972
&(buf_pointers[3]->cue_buffer), &(buf_pointers[4]->cue_buffer));
976
fs_add6channels(out_buf, &(buf_pointers[0]->cue_buffer),
977
&(buf_pointers[1]->cue_buffer), &(buf_pointers[2]->cue_buffer),
978
&(buf_pointers[3]->cue_buffer), &(buf_pointers[4]->cue_buffer),
979
&(buf_pointers[5]->cue_buffer));
983
fs_add7channels(out_buf, &(buf_pointers[0]->cue_buffer),
984
&(buf_pointers[1]->cue_buffer), &(buf_pointers[2]->cue_buffer),
985
&(buf_pointers[3]->cue_buffer), &(buf_pointers[4]->cue_buffer),
986
&(buf_pointers[5]->cue_buffer), &(buf_pointers[6]->cue_buffer));
990
fs_add8channels(out_buf, &(buf_pointers[0]->cue_buffer),
991
&(buf_pointers[1]->cue_buffer), &(buf_pointers[2]->cue_buffer),
992
&(buf_pointers[3]->cue_buffer), &(buf_pointers[4]->cue_buffer),
993
&(buf_pointers[5]->cue_buffer), &(buf_pointers[6]->cue_buffer),
994
&(buf_pointers[7]->cue_buffer));
998
Error("add_cue_audio: fs_addNchannels NOT IMPLEMENTED!!!!!!!!");
999
/* fs_addNchannels(out_buf,buf_pointers,sysdata->num_channels);*/
1008
run_it - executes the channel listener loop, applies Fourier Synthesis when
1011
Note that two different timeout values are used with select.
1012
While audio is being played, the smaller value is being used.
1013
Once a timeout occurs, the larger value will be used.
1014
This way the audio pause command can be issued a short time
1015
after audio has stopped, and cleanup the audio output in case
1018
inputs - the input channel pipes
1019
outputs - the fourier synthesis of the pipes is sent to the soundcard.
1023
static int select_result,result,channel_count,cue_count,numch;
1024
static int i,checknum;
1025
/*pointers to arrays of signed shorts*/
1026
static local_channel ** buf_pointers;
1027
static local_channel ** temp_buf_pointers;
1028
static local_channel ** cue_pointers;
1029
static local_channel ** temp_cue_pointers;
1031
static fd_set temp_read_set;
1032
static struct timeval timeout;
1033
static int timeout_value_sec;
1034
static int timeout_value_usec;
1037
static struct local_channel_s *temp_ch;
1038
static struct local_channel_s *temp_cue;
1039
static struct channel_buf_s *temp_buf;
1040
static int total_timeout_count,current_timeout_count;
1041
static int local_cue;
1042
static int pause_flag;
1045
/* static int loop_count = 0; */
1047
/* init local vars */
1048
result = select_result = channel_count = cue_count = i = 0;
1050
checknum = total_timeout_count = current_timeout_count = 0;
1052
/* set number of (io fd's to check) to be the max read fd + 1 */
1053
numch = local_channels[sysdata->num_channels-1].server_comm_fd + 1;
1055
/* allocate the temporary buf pointers */
1056
buf_pointers = (local_channel **) malloc(sizeof(local_channel*) * sysdata->num_channels);
1057
cue_pointers = (local_channel **) malloc(sizeof(local_channel*) * sysdata->num_channels);
1059
for (i = 0; i < sysdata->num_channels; i++)
1061
buf_pointers[i] = NULL;
1064
free_channels_flag = TRUE;
1070
/* set initial timeout to be 5 seconds */
1071
timeout_value_sec = MIN_TIMEOUT_VALUE_SEC;
1072
timeout_value_usec = MIN_TIMEOUT_VALUE_USEC;
1076
/* reset audio if necessary */
1077
if (reset_audio_flag)
1079
reset_audio_flag = 0;
1081
if (main_audio != NULL)
1083
close_audio(main_audio);
1087
Debug("Re-opening main audio device.");
1089
if ((main_audio = init_audio(sysdata->main_audio_device,O_WRONLY,stdout_flag,
1090
sysdata->num_main_buffs)) == NULL)
1092
Error("Could not open main audio device.");
1097
Debug("Re-opening cue audio device...");
1099
if (cue_audio != NULL)
1101
close_audio(cue_audio);
1105
if ((cue_audio = init_audio(sysdata->cue_audio_device,
1106
O_WRONLY/* | O_NONBLOCK */,
1107
stdout_flag,sysdata->num_cue_buffs)) == NULL)
1109
Error("Could not open cue audio device.");
1113
Debug("Audio is reset.");
1116
/******* Handle IO *******/
1118
/* reset file descriptor set */
1119
FD_ZERO(&temp_read_set);
1120
temp_read_set = read_ch_set;
1122
/* reset temp_buf_pointer and channel pointer */
1123
temp_buf_pointers = buf_pointers;
1124
temp_cue_pointers = cue_pointers;
1126
temp_ch = local_channels;
1127
temp_cue = local_channels;
1130
channel_count = cue_count = 0;
1132
/* check to see if any descriptors are ready...
1133
select returns -1 on an interrupt, which is handled elsewhere,
1134
and returns 0 on timeout. */
1136
timeout.tv_sec = timeout_value_sec;
1137
timeout.tv_usec = timeout_value_usec;
1139
select_result = select(numch,&temp_read_set,(fd_set*) 0,(fd_set*) 0, &timeout);
1141
/* verify that all pipes have enough data in them */
1142
if (select_result > 0)
1146
timeout_value_sec = MIN_TIMEOUT_VALUE_SEC;
1147
timeout_value_usec = MIN_TIMEOUT_VALUE_USEC;
1149
/* set through channels and see if data is ready */
1150
for (i=0; i < sysdata->num_channels;i++)
1152
if (FD_ISSET(temp_ch->server_comm_fd,&temp_read_set))
1154
/* get amount of data in the buffer */
1155
if (ioctl(temp_ch->server_comm_fd,FIONREAD,&result) != 0)
1157
perror("FIONREAD FAILED!!! ");
1161
if (result < DB_BUFSIZE_CHAR)
1163
/* sleep for 5000 miroseconds and wait for data to arrive on the pipe.
1164
the 5000 is becuase this is slightly less than
1165
the amount of sound data in a 1024 byte buffer */
1169
temp_ch->skip_count++;
1171
tv.tv_sec = usec / 1000000;
1172
usec -= tv.tv_sec * 1000000;
1174
select(0, NULL, NULL, NULL, &tv);
1176
/* force the for loop to exit to minimize sleeps */
1177
i = sysdata->num_channels;
1179
/* to prevent pausing all output, if less than a buffers worth
1180
of data is sitting in the pipe for more than SKIP_MAX iterations,
1181
then clean the pipe out */
1182
if (temp_ch->skip_count < sysdata->skip_max) skipnum++;
1190
/* if there is a pipe without enough data, then skip the I/O section of the
1191
loop so that the pipe has time to catch up */
1192
if (skipnum) continue;
1194
temp_ch = local_channels;
1196
/* check each channel to see if data is ready */
1197
for (i=0; i < sysdata->num_channels;i++)
1199
/* grab cue value for use inside the critical section */
1200
local_cue = temp_ch->cue;
1202
if (FD_ISSET(temp_ch->server_comm_fd,&temp_read_set))
1204
switch (temp_ch->channel_type)
1207
/* get buffer to read pipe data to, always use buffer1 */
1208
temp_buf = &(temp_ch->buffer);
1209
result = read(temp_ch->server_comm_fd,temp_buf->buf,
1211
temp_buf->len = result;
1212
temp_ch->skip_count = 0;
1214
case SOCKET_CHANNEL:
1215
Error("Socket channels not yet implemented.");
1218
Error("Unknown channel type.");
1222
/* if we read data, then add it to the buffer array */
1225
/* remember buffer cause temp_ch->buffer-> requires a useless
1226
extra addition... depends on how smart the compiler is... */
1227
temp_buf = &(temp_ch->buffer);
1228
temp_buf->data_ready = TRUE;
1230
/* see if this channel was previously free, if so then update
1231
the free channel symlink also, toss out this buffer of info
1232
because it is the init buffer written by DBAudio_Init() */
1233
if (temp_ch->is_symlink)
1237
Debug("New data on %s",temp_ch->comm_filename);
1238
PrintChannelSettings(temp_ch);
1240
temp_ch->is_symlink = FALSE;
1241
temp_ch->free_channel = FALSE;
1244
/* clear cue buffer data for synch.*/
1249
result = read(temp_ch->server_cue_fd,temp_buf->buf,
1256
/* calculate check value for buffer zeroing */
1257
checknum = DB_BUFSIZE_CHAR - temp_buf->len;
1258
/* if the max # of bytes wasn't read, then blank the tail of the buffer*/
1261
Debug("cleared %d bytes",checknum);
1262
/* divide by two since buf is signed shorts which are 2 bytes long */
1264
memset(temp_buf->buf + (temp_buf->len /
1265
sizeof(signed short)),0,checknum);
1268
/* keep a pointer to the buffer that has data_ready */
1269
temp_buf_pointers[channel_count] = temp_ch;
1272
/* we read the cue data here becuase, cue data exists only
1273
if data exists on the main input. It is easier to use the
1274
main input pipe to detect data ready. */
1275
if (cue_flag && local_cue)
1277
temp_buf = &(temp_ch->cue_buffer);
1278
result = read(temp_ch->server_cue_fd,temp_buf->buf,
1283
temp_buf->len = result;
1284
temp_buf->data_ready = TRUE;
1286
/* calculate check value for buffer zeroing*/
1287
checknum = DB_BUFSIZE_CHAR - temp_buf->len;
1288
/* if the max # of bytes wasn't read, then blank the tail of the buffer*/
1291
/* divide by two since buf is signed shorts which are 2 bytes long */
1292
memset(temp_buf->buf + (temp_buf->len /
1293
sizeof(signed short)),0,checknum);
1296
/* keep a pointer to the buffer that has data_ready */
1297
temp_cue_pointers[cue_count] = temp_ch;
1299
} /* end if result > 0 */
1301
} /* end cue_flag */
1303
} /*end if result */
1306
/* Now there is a probable EOF situation so remove the pipe, and reopen it */
1307
Debug("Handling pipe EOF: %s",temp_ch->comm_filename);
1309
FD_CLR(temp_ch->server_comm_fd,&read_ch_set);
1311
reset_channel(temp_ch,TRUE);
1313
/*check the symlink*/
1314
if (!free_channels_flag)
1316
Debug("Channels in use is now less than Maximum.");
1317
free_channels_flag = TRUE;
1321
} /*end fd_set check*/
1326
/*write main channel data*/
1327
if (add_main_audio(output_buf,buf_pointers,channel_count) != NULL)
1332
if (add_cue_audio(cue_output_buf,cue_pointers,cue_count) != NULL)
1334
/* handle cue split */
1335
if (sysdata->cue_split)
1337
int tempval, tempval2;
1338
short * tempout, *tempout2;
1341
tempout = (short *) output_buf;
1342
tempout2 = (short *) cue_output_buf;
1344
tempout = output_buf;
1345
tempout2 = cue_output_buf;
1347
for(i = 0; i < DB_BUFSIZE_SHORT/2; i++)
1349
/* get output sample */
1350
tempval = (int)(((float)tempout[0]) + ((float)(tempout[1])));
1351
/* get cue sample */
1352
tempval2 = (int)(((float)tempout2[0]) + ((float)(tempout2[1])));
1354
if(tempval > 32767) {tempval = 32767;}
1355
if(tempval < -32688) {tempval = -32767;}
1356
if(tempval2 > 32767) {tempval2 = 32767;}
1357
if(tempval2 < -32688) {tempval2 = -32767;}
1359
/* add to cue buffer */
1360
*tempout2 = (short)tempval;
1362
*tempout2 = (short)tempval2;
1370
if (single_output_flag)
1372
memcpy(output_buf,cue_output_buf,DB_BUFSIZE_CHAR);
1376
if (write_audio(cue_audio,cue_output_buf,DB_BUFSIZE_CHAR) <= 0)
1378
perror("error outputing cue data ");
1382
else /* add_cue_audio */
1384
if (single_output_flag)
1386
/* create mono output of master and set cue to zero */
1388
int tempval, tempval2;
1389
short * tempout, *tempout2;
1392
tempout = (short *) output_buf;
1393
tempout2 = (short *) cue_output_buf;
1395
tempout = output_buf;
1396
tempout2 = cue_output_buf;
1398
for(i = 0; i < DB_BUFSIZE_SHORT/2; i++)
1400
/* get output sample */
1401
tempval = (int)(((float)tempout[0]) + ((float)(tempout[1])));
1402
/* get cue sample */
1403
tempval2 = (int)(((float)tempout2[0]) + ((float)(tempout2[1])));
1405
if(tempval > 32767) {tempval = 32767;}
1406
if(tempval < -32688) {tempval = -32767;}
1407
if(tempval2 > 32767) {tempval2 = 32767;}
1408
if(tempval2 < -32688) {tempval2 = -32767;}
1410
/* add to cue buffer */
1411
*tempout = (short)tempval;
1413
*tempout = (short)0;
1422
write_audio(cue_audio,empty_buf,DB_BUFSIZE_CHAR);
1424
/* memset(cue_output_buf,0,DB_BUFSIZE_CHAR); */
1425
} /* add cue audio */
1426
} /* end write cue data */
1428
if (write_audio(main_audio,output_buf,DB_BUFSIZE_CHAR) <= 0)
1430
perror("error outputing main data ");
1433
/* if we are recording, write data to file */
1434
if (record_fid != NULL)
1436
/* make sure there is space in the file, Max is ~4GB */
1437
if (record_count < (MAX_WAV_LENGTH - DB_BUFSIZE_CHAR))
1439
record_count += fwrite(output_buf,1,DB_BUFSIZE_CHAR,record_fid);
1443
/* out of space, stop recording */
1445
Error("DBFSD: ran out of space while recording output.");
1449
} /* add_main_audio */
1450
} /*end if select_result*/
1453
if (select_result == 0)
1455
Debug("Timeout total: %d since last sample: %d (minutes)",total_timeout_count,current_timeout_count);
1456
total_timeout_count++;
1457
current_timeout_count++;
1459
/* since no audio has occured, set longer timeout */
1460
timeout_value_sec = MAX_TIMEOUT_VALUE_SEC;
1461
timeout_value_usec = MAX_TIMEOUT_VALUE_USEC;
1465
Debug("Pausing main audio...");
1466
pause_audio(main_audio);
1470
Debug("Pausing cue audio...");
1471
pause_audio(cue_audio);
1478
/*received an error on select, check which one it is.*/
1479
if (select_result == -1)
1484
Error("EBADF: invalid descriptors for select.\n");
1487
Debug("EINTR: select returned due to interrupt.\n");
1490
Error("EINVAL: invalid parameters to select.\n");
1492
default: Error("Unknown error on select.\n"); break;
1494
} /*end if select_result*/
1501
/***************************************************************************/
1503
/***************************************************************************/
1505
int main (int argc, char *argv[])
1509
printf("WARNING!!! This program has been compiled with environment options specific to the head DBMix developer. It may not work on your system!!!\n");
1513
local_channels = NULL;
1516
Debug("sysdata allocated.");
1517
parse_cmdline(argc,argv);
1519
Debug("cmdline parsed.");
1520
Debug("pid is: %d\n",sysdata->pid);
1522
Debug("Begining initialization...\n");
1524
/*init audio, this *must* be done before the call to init_channels*/
1526
/* open audio device */
1527
/* if a device was not specified on the command line, then
1528
use the hardcoded defaults. */
1529
Debug("Opening master audio device... %s...",sysdata->main_audio_device);
1531
main_audio = cue_audio = NULL;
1533
if ((main_audio = init_audio(sysdata->main_audio_device,O_WRONLY,stdout_flag,
1534
sysdata->num_main_buffs)) == NULL)
1536
Error("Could not open main audio device.");
1540
if (single_output_flag)
1542
Debug("WARNING!!! Cue will be output as a channel of the master output!!!!\n");
1549
Debug("Opening cue audio device...");
1551
if ((cue_audio = init_audio(sysdata->cue_audio_device,
1552
O_WRONLY/* | O_NONBLOCK */,
1553
0,sysdata->num_cue_buffs)) == NULL)
1555
Error("Could not open cue audio device.");
1561
Debug("audio initialized.");
1563
if (init_channels() != SUCCESS)
1564
{shutdown_dbfsd(); return -1;}
1566
Debug("channels initialized.");
1568
/*install signal handlers*/
1569
reset_audio_flag = 0;
1571
signal(SIGINT,sigexit);
1572
signal(SIGTERM,sigexit);
1573
signal(SIGCONT,sigcont);
1574
signal(SIGHUP,sighup);
1575
signal(SIGUSR1,sigusr1);
1576
signal(SIGUSR2,sigusr2);
1578
Debug("Initialization complete... running... \n");
1582
Debug("Run_it complete.");