~ubuntu-branches/ubuntu/trusty/dbmix/trusty

« back to all changes in this revision

Viewing changes to dbfsd_src/dbfsd.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2003-06-09 21:54:06 UTC
  • Revision ID: james.westby@ubuntu.com-20030609215406-8c0wou3z9jdk3gwp
Tags: upstream-0.9.8
ImportĀ upstreamĀ versionĀ 0.9.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  DB Fourier Synthesis Daemon 
 
3
  ===========================
 
4
  
 
5
  Description:
 
6
  -----------
 
7
  This deamon creates input "channels" using pipes and network sockets,
 
8
  and then combines their input for writing to /dev/dsp.
 
9
 
 
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.
 
13
 
 
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.
 
18
 
 
19
  This software is brought to you by the letter A and the number 4
 
20
 
 
21
  Version: see VRESION_STR declared below
 
22
  Author:  Bob Dean
 
23
  Copyright (c) 1999, 2000
 
24
 
 
25
 
 
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.
 
30
 
 
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.
 
35
 
 
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.
 
39
 
 
40
*/
 
41
 
 
42
/*
 
43
 
 
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
 
48
 
 
49
 */
 
50
 
 
51
/*
 
52
  Design notes:
 
53
 
 
54
  Use of signals:
 
55
  SIGINT  - shut down
 
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.
 
60
 
 
61
 */
 
62
 
 
63
 
 
64
#include <stdio.h>
 
65
#include <unistd.h>
 
66
#include <fcntl.h>
 
67
#include <stdlib.h>
 
68
#include <string.h>
 
69
#include <errno.h>
 
70
#include <signal.h>
 
71
#include <limits.h>
 
72
#include <stdarg.h>
 
73
#include <sys/ioctl.h>
 
74
#include <sys/types.h>
 
75
#include <sys/time.h>
 
76
#include <sys/shm.h>
 
77
#include <sys/ipc.h>
 
78
#include <sys/sem.h>
 
79
#include <sys/stat.h>
 
80
#include <sys/msg.h>
 
81
 
 
82
#include <dbsoundcard.h>
 
83
 
 
84
#include "dbaudio.h"
 
85
#include <dbchannel.h>
 
86
#include "fsadders.h"
 
87
#include <dbdebug.h>
 
88
 
 
89
/* local defines */
 
90
#define DBFSD_VERSION_STR   "A.12"
 
91
 
 
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
 
97
 
 
98
/* local global variables */
 
99
extern int errno;
 
100
extern int debug_level;
 
101
 
 
102
/* local prototypes */
 
103
void shutdown_dbfsd();
 
104
 
 
105
/***************************************************************************/
 
106
/*  Global variables                                                       */
 
107
/***************************************************************************/
 
108
 
 
109
/* daemon system data*/
 
110
dbfsd_data * sysdata;
 
111
 
 
112
int loop_flag;   /*main loop flag*/
 
113
int free_channels_flag;
 
114
int cue_flag;
 
115
int single_output_flag;
 
116
int reset_audio_flag;
 
117
 
 
118
int shmid;     /* shared memory id for channels*/
 
119
int sysshmid;  /* shared memory id for dbfsd_data*/
 
120
int semid;      /* channel semaphore id  */
 
121
 
 
122
FILE * record_fid;
 
123
gint record_count;
 
124
wav_header header;
 
125
 
 
126
/*channel arrays*/
 
127
local_channel *local_channels, *cue_channels;
 
128
/* socket_channel **socket_channels; */
 
129
 
 
130
char tempdirstr[512], cue_tempdirstr[512];
 
131
 
 
132
/*flags to hold cmdline switches*/
 
133
int stdout_flag;
 
134
int quiet_flag;
 
135
 
 
136
fd_set read_ch_set; /*fd set for select*/
 
137
 
 
138
signed short output_buf[DB_BUFSIZE_SHORT], cue_output_buf[DB_BUFSIZE_SHORT], empty_buf[DB_BUFSIZE_SHORT];
 
139
 
 
140
/* signed short *output_buf, *cue_output_buf, *empty_buf; */
 
141
 
 
142
oss_control_struct * main_audio, * cue_audio;
 
143
 
 
144
/***************************************************************************/
 
145
/*  Initialization functions                                               */
 
146
/***************************************************************************/
 
147
 
 
148
/*
 
149
  print_version - outputs version info to stdout
 
150
 */
 
151
void print_version()
 
152
{
 
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);
 
157
}
 
158
 
 
159
/*
 
160
  print_greeting - outputs to stdout a greeting
 
161
  
 
162
  inputs: none
 
163
  outputs: none
 
164
*/
 
165
void print_help()
 
166
{
 
167
        print_version();
 
168
 
 
169
        printf("\n");
 
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");
 
182
        printf("\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");
 
186
        printf("\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");
 
191
  
 
192
        printf("\n");
 
193
}
 
194
 
 
195
 
 
196
/*
 
197
  parse_cmdline - steps through argv and sets all the variables
 
198
 
 
199
  inputs - argc argv
 
200
  outputs - sets system variables
 
201
 */
 
202
void parse_cmdline(int argc, char* argv[])
 
203
{
 
204
        int opt;
 
205
 
 
206
        /* init arguments... */
 
207
        quiet_flag = FALSE;
 
208
        stdout_flag = FALSE;
 
209
        cue_flag = FALSE;
 
210
        single_output_flag = FALSE;
 
211
 
 
212
        record_fid = NULL;
 
213
 
 
214
        sprintf(tempdirstr,"/tmp/ch");
 
215
        sysdata->cue_audio_device[0] = '\0';
 
216
        cue_tempdirstr[0] = '\0';
 
217
 
 
218
        sysdata->pid = getpid();
 
219
        strcpy(sysdata->main_audio_device,DEFAULT_AUDIO_DEVICE);
 
220
 
 
221
        /* parse argv */
 
222
        while ((opt = getopt(argc,argv,"n:s:a:b:ovqhdcer:")) != -1)
 
223
        {
 
224
                switch (opt)
 
225
                {
 
226
                        case 'h':
 
227
                                print_help();
 
228
                                shutdown_dbfsd();
 
229
                                break;
 
230
                        case 'a':
 
231
                                strcpy(sysdata->main_audio_device,optarg);
 
232
                                Debug("Set master audio device to be: \"%s\"",sysdata->main_audio_device);
 
233
                                break;
 
234
                        case 'b':
 
235
                                strcpy(sysdata->cue_audio_device,optarg);
 
236
                                Debug("Set cue audio device to be: \"%s\"",sysdata->cue_audio_device);
 
237
                                break;
 
238
                        case 'e':
 
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 */
 
244
                        case 'c':
 
245
                                cue_flag = TRUE;
 
246
                                sysdata->cue_enabled = TRUE;
 
247
                                Debug("set cue flag.");
 
248
                                break;
 
249
                        case 'v':
 
250
                                print_version();
 
251
                                shutdown_dbfsd();
 
252
                        case 'n':
 
253
                                sysdata->num_channels = atoi(optarg);
 
254
                                printf("sysdata->num_channels set %d\n",sysdata->num_channels);
 
255
                                break;
 
256
                        case 'o':
 
257
                                stdout_flag = TRUE;
 
258
                                Debug("output to stdout");
 
259
                                break;
 
260
                        case 'q':   /* I wish I could remember what this was for... */
 
261
                                quiet_flag = TRUE;
 
262
                                Debug("quiet flag set");
 
263
                                break;
 
264
                        case 'r':
 
265
                                sysdata->num_main_buffs = atoi(optarg);
 
266
 
 
267
                                if (sysdata->num_main_buffs < DB_MIN_AUDIO_BUFFS)
 
268
                                {
 
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;
 
271
                                }
 
272
 
 
273
                                sysdata->num_cue_buffs = sysdata->num_main_buffs;
 
274
                                Debug("num audio buffs set %d\n",sysdata->num_main_buffs);
 
275
                        case 's':
 
276
                                sysdata->num_sockets = atoi(optarg);
 
277
                                Debug("numsockets set %d\n",sysdata->num_sockets);
 
278
                                break;
 
279
                        case 'd':
 
280
                                sysdata->debug_level = debug_level = 1;
 
281
                                Debug("debug level set\n");
 
282
                                break;
 
283
                        case ':':
 
284
                                printf("option needs a value\n");
 
285
                                break;
 
286
                        case '?':
 
287
                                printf("unknown option: %c\n",optopt);
 
288
                                exit(0);
 
289
                                break;
 
290
                        default: break;
 
291
                }
 
292
        } /*end while*/
 
293
 
 
294
        if (cue_flag)
 
295
        {
 
296
                sprintf(cue_tempdirstr,"/tmp/cue");
 
297
 
 
298
                if (sysdata->cue_audio_device[0] == '\0')
 
299
                {
 
300
                        strcpy(sysdata->cue_audio_device,DEFAULT_CUE_AUDIO_DEVICE);     
 
301
                }
 
302
 
 
303
                sysdata->cue_pid = getpid();
 
304
        }
 
305
 
 
306
}
 
307
 
 
308
 
 
309
 
 
310
/*
 
311
  init_sysdata - allocates shared memory to hold the system dbfsd_data struct
 
312
 
 
313
      inputs - none
 
314
      outputs - none
 
315
      side effects - allocates a chunk of shared memory and point to it with sysdata
 
316
 */
 
317
void init_sysdata()
 
318
{
 
319
        /*allocate ssytem data struct*/
 
320
        sysshmid = shmget((key_t) DB_SYSTEM_SM_KEY, sizeof(dbfsd_data), 
 
321
                                          0666 | O_RDWR | IPC_CREAT);
 
322
 
 
323
        if (sysshmid == -1) 
 
324
        {
 
325
                Error("init_sysdata: error creating shared memory for system data.");
 
326
 
 
327
                exit(EXIT_FAILURE); 
 
328
        }
 
329
 
 
330
        sysdata = shmat(sysshmid,(void *)0, 0);
 
331
   
 
332
        if ((int)sysdata == -1)
 
333
        {
 
334
                Error("init_sysdata: error attaching system data shared memory.");
 
335
       
 
336
                if (shmdt(sysdata) == -1)
 
337
                {
 
338
                        Error("init_sysdata: could not detach system data memory segment.");
 
339
                }
 
340
        
 
341
                if (shmctl(sysshmid,IPC_RMID, 0) == -1)
 
342
                {
 
343
                        Error("init_sysdata: could not delete system data shared memory segment.");
 
344
                }
 
345
 
 
346
                exit(EXIT_FAILURE);
 
347
        }
 
348
 
 
349
        Debug("init_sysdata: system data shared memory attached successfully.");
 
350
   
 
351
        memset(sysdata->filename,0,FILENAME_MAX);
 
352
 
 
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;
 
376
}
 
377
 
 
378
 
 
379
 
 
380
int reset_channel(local_channel * ch, int reset)
 
381
{       
 
382
        char      tempstr[256];
 
383
 
 
384
        if (reset)
 
385
        {
 
386
                Debug("Reseting channel %d...",ch->index);
 
387
                Debug("  Closing and unlinking pipes...");
 
388
                
 
389
                close(ch->server_comm_fd);
 
390
                unlink(ch->comm_filename);
 
391
                close(ch->server_cue_fd);
 
392
                unlink(ch->cue_filename);
 
393
           
 
394
                Debug("  closing message queue...");
 
395
 
 
396
                if (msgctl(ch->msg_q_id,IPC_RMID,0) != SUCCESS)
 
397
                {
 
398
                        Error("Failed to delete message queue on channel %d",ch->index);
 
399
                }
 
400
        }
 
401
        else
 
402
        {
 
403
                Debug("  Creating channel %d...",ch->index);
 
404
        }
 
405
 
 
406
        /* intialize the channel name to "Channel x" */
 
407
        sprintf(ch->channel_name,"Channel - %d",ch->index+1);
 
408
 
 
409
        Debug("  Set channel name to: %s",ch->channel_name);
 
410
 
 
411
        /* create message queue */
 
412
        ch->msg_q_id = msgget(DB_CHANNELS_Q_KEY_BASE + ch->index, 0666 | IPC_CREAT);
 
413
 
 
414
        if (ch->msg_q_id == -1)
 
415
        {
 
416
                Error("Failed to create message queue on channel %d",ch->index);
 
417
        }
 
418
        
 
419
        Debug("  reset_channel: Opened message queue.");
 
420
 
 
421
        /* create comm pipe */
 
422
        if (mkfifo(ch->comm_filename,0777) != 0) 
 
423
        { 
 
424
                if (errno != EEXIST)
 
425
                {
 
426
                        sprintf(tempstr,"reset_channel: Error creating %s",ch->comm_filename);
 
427
                        perror(tempstr); return FAILURE;
 
428
                }
 
429
        }
 
430
       
 
431
        /* open comm pipe */
 
432
        if ((ch->server_comm_fd = open(ch->comm_filename,
 
433
                                                                   O_RDONLY | O_NONBLOCK )) == -1)
 
434
        { 
 
435
                sprintf(tempstr,"reset_channel: Error opening %s for read:",ch->comm_filename);
 
436
                perror(tempstr); 
 
437
                return FAILURE; 
 
438
        }
 
439
 
 
440
        Debug("  reset_channel: opened pipe %s",ch->comm_filename);
 
441
      
 
442
        if (cue_flag)
 
443
        {
 
444
                /* create cue pipe */
 
445
                Debug("  reset_channel: creating cue pipe...");
 
446
 
 
447
                if (mkfifo(ch->cue_filename,0777) != 0)
 
448
                { 
 
449
                        if (errno != EEXIST)
 
450
                        {
 
451
                                sprintf(tempstr,"reset_channel: Error creating %s",
 
452
                                                ch->cue_filename);
 
453
                                perror(tempstr); 
 
454
                                return FAILURE;
 
455
                        }
 
456
                }
 
457
                
 
458
                /* open cue pipe */
 
459
                Debug("  reset_channel: Opening cue pipe...");
 
460
                if ((ch->server_cue_fd = open(ch->cue_filename,O_RDONLY | O_NONBLOCK )) == -1)
 
461
                { 
 
462
                        sprintf(tempstr,"reset_channel: Error opening %s for read:",
 
463
                                        ch->cue_filename);
 
464
                        perror(tempstr); 
 
465
                        return FAILURE; 
 
466
                }
 
467
                
 
468
                ch->channel_flags |= CUE_FLAG;
 
469
 
 
470
                Debug("  reset_channel: opened pipe %s",ch->cue_filename);
 
471
        }
 
472
        else
 
473
        {
 
474
                ch->channel_flags &= ~CUE_FLAG;
 
475
                ch->cue_filename[0] = '\0';
 
476
                ch->server_cue_fd = -1;
 
477
        }
 
478
 
 
479
        /*add to select set*/
 
480
        FD_SET(ch->server_comm_fd,&read_ch_set);
 
481
 
 
482
        ch->msg_flags = 0;
 
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;
 
489
        ch->cue = FALSE;
 
490
        ch->base_pitch = DEFAULT_PITCH;
 
491
        ch->user_pitch = DEFAULT_PITCH;
 
492
        ch->message_handler = NULL;
 
493
        ch->pause = FALSE;
 
494
        ch->mute = FALSE;
 
495
        ch->skip_count = 0;
 
496
 
 
497
        ch->writing = 0;
 
498
 
 
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;
 
508
 
 
509
        /* init default channel flags */
 
510
        ch->channel_flags |= (PITCH_FLAG | PAUSE_FLAG);
 
511
 
 
512
        Debug("  reset_channel: channel %d reset.",ch->index);
 
513
 
 
514
        return SUCCESS;
 
515
}
 
516
 
 
517
 
 
518
/*
 
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.
 
522
*
 
523
*        inputs:  str - filesystem location for FIFO's
 
524
*                 num - number of channels
 
525
*        outputs: error codes...
 
526
*/
 
527
int init_channels()
 
528
{
 
529
        int len,i;
 
530
        local_channel* temp_ch;
 
531
        key_t channels_key;
 
532
 
 
533
        len = strlen(tempdirstr) + 20;
 
534
 
 
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); */
 
538
 
 
539
        memset(empty_buf,0,DB_BUFSIZE_CHAR);
 
540
 
 
541
        channels_key = DB_CHANNELS_SM_KEY;
 
542
        
 
543
        Debug("init_channels: samples per channel buffer %d",DB_BUFSIZE_SHORT);
 
544
 
 
545
        /* allocate input channel control structs */
 
546
        shmid = shmget(channels_key, ((sysdata->num_channels) * sizeof(local_channel)), 0666 | O_RDWR | IPC_CREAT);
 
547
 
 
548
        if (shmid == -1) 
 
549
        {
 
550
                Error("init_channels: error creating shared memory.");
 
551
 
 
552
            shutdown_dbfsd(); 
 
553
        }
 
554
   
 
555
        local_channels = shmat(shmid,(void *)0, 0);
 
556
   
 
557
        if ((int)local_channels == -1)
 
558
        {
 
559
                Error("init_channels: error attaching shared memory.");
 
560
       
 
561
                if (shmdt(local_channels) == -1)
 
562
                {
 
563
                        Error("init_channels: could not detach memory segment.");
 
564
                }
 
565
        
 
566
                if (shmctl(shmid,IPC_RMID, 0) == -1)
 
567
                {
 
568
                        Error("init_channels: could not delete shared memory segment.");
 
569
                }
 
570
 
 
571
                shutdown_dbfsd();
 
572
        }
 
573
 
 
574
        Debug("init_channels: shared memory attached successfully.");
 
575
 
 
576
        FD_ZERO(&read_ch_set);
 
577
        
 
578
        temp_ch = local_channels;
 
579
 
 
580
        /*initialize channels*/
 
581
        for (i = 0; i < sysdata->num_channels; i++)
 
582
        {
 
583
                local_channels[i].channel_flags = 0;
 
584
 
 
585
                /*create comm pipe filename*/      
 
586
                sprintf(local_channels[i].comm_filename,"%s%d_comm",tempdirstr,i+1);
 
587
                /*create cue filename*/
 
588
                if (cue_flag)
 
589
                {
 
590
                        sprintf(local_channels[i].cue_filename,"%s%d_cue",tempdirstr,i+1);
 
591
                }
 
592
                else
 
593
                {
 
594
                        local_channels[i].cue_filename[0] = '\0';
 
595
                }
 
596
 
 
597
                local_channels[i].index = i;
 
598
                reset_channel(temp_ch,FALSE);
 
599
                temp_ch++;
 
600
        }
 
601
 
 
602
        return SUCCESS;
 
603
}
 
604
 
 
605
 
 
606
/*
 
607
 sigexit - changes system variables to force clean shutdown
 
608
 inputs - none
 
609
 outputs - none
 
610
 */
 
611
void sigexit(int signum)
 
612
{
 
613
        loop_flag = FALSE;
 
614
        Debug("Sigexit has been called.");
 
615
}
 
616
 
 
617
 
 
618
void sigcont(int signum)
 
619
{
 
620
        Debug("Sigcont has been called.");
 
621
}
 
622
 
 
623
 
 
624
/*
 
625
  sighup - callback when a SIGHUP signal is recieved, resets audio devices
 
626
 */
 
627
void sighup(int signum)
 
628
{
 
629
        Debug("sighup has been called.");
 
630
 
 
631
        reset_audio_flag = 1;
 
632
}
 
633
 
 
634
 
 
635
/*
 
636
  sigusr - callback when a SIGUSR signal is recieved, starts recording to disk.
 
637
 */
 
638
void sigusr1(int signum)
 
639
{
 
640
        Debug("sigusr1 has been called.");
 
641
        
 
642
        /* if not recording, start recording */
 
643
        if (record_fid == NULL)
 
644
        {
 
645
                sysdata->recording = 1;
 
646
 
 
647
                /* open file */
 
648
                record_fid = fopen(sysdata->filename,"wb");
 
649
 
 
650
                if (!record_fid)
 
651
                {
 
652
                        Error("DBFSD: Could not open output file for recording.\n");
 
653
                        return;
 
654
                }
 
655
                
 
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);
 
670
 
 
671
                /* init data count to zero */
 
672
                record_count = 0;
 
673
 
 
674
                /* write wav header */
 
675
                fwrite(&header, sizeof(wav_header), 1, record_fid);
 
676
        }
 
677
}
 
678
 
 
679
 
 
680
/*
 
681
  sigusr2 - callback for SIGUSR2 signal, stops recording to disk
 
682
 */
 
683
void sigusr2(int signum)
 
684
{
 
685
        Debug("sigusr2 has been called");
 
686
 
 
687
        if (record_fid != NULL)
 
688
        {
 
689
                sysdata->recording = 0;
 
690
 
 
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);
 
694
 
 
695
                fseek(record_fid, 0, SEEK_SET);
 
696
                fwrite(&header, sizeof(wav_header), 1, record_fid);
 
697
                fclose(record_fid);
 
698
 
 
699
                record_count = 0;
 
700
                record_fid = NULL;
 
701
        }
 
702
}
 
703
 
 
704
 
 
705
/*
 
706
 shutdown - frees all resources before exiting. 
 
707
 * 
 
708
 No need to free the global malloc'd bits here since the system process
 
709
 cleanup will take care of it...
 
710
 * 
 
711
  inputs - none
 
712
  outputs - none
 
713
 */
 
714
void shutdown_dbfsd()
 
715
{
 
716
        int i;
 
717
 
 
718
        Debug("closing...");
 
719
 
 
720
        Debug("removing channels:");
 
721
 
 
722
        unlink(tempdirstr);
 
723
        
 
724
        if(local_channels != NULL)
 
725
        {
 
726
                for (i = 0; i < sysdata->num_channels;i++)
 
727
                {
 
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)
 
734
                        {
 
735
                                Error("shutdown_dbfsd: could not delete message queue.");
 
736
                        }
 
737
                }
 
738
 
 
739
                Debug("deleteing shared memory segment for channel data... ");
 
740
                
 
741
                if (shmdt(local_channels) == -1)
 
742
                {
 
743
                        Error("shutdown_dbfsd: could not detach memory segment.");
 
744
                }
 
745
                
 
746
                if (shmctl(shmid,IPC_RMID, 0) == -1)
 
747
                {
 
748
                        Error("shutdown_dbfsd: could not delete shared memory segment.");
 
749
                }
 
750
        }
 
751
 
 
752
        Debug("deleteing system data shared memory segment... ");
 
753
 
 
754
        if (shmdt(sysdata) == -1)
 
755
        {
 
756
                Error("shutdown_dbfsd: could not detach system data memory segment.");
 
757
        }
 
758
 
 
759
        if (shmctl(sysshmid,IPC_RMID, 0) == -1)
 
760
        {
 
761
                Error("shutdown_dbfsd: could not delete system data shared memory segment.");
 
762
        }
 
763
 
 
764
        Debug("closing audio devices...");
 
765
 
 
766
        close_audio(cue_audio);
 
767
        close_audio(main_audio);
 
768
 
 
769
        Debug("done.\nthank you for using DBfsd.");
 
770
        /*I can never remember if this should be a 0 or a 1...*/
 
771
 
 
772
        exit(0);
 
773
}
 
774
 
 
775
 
 
776
/*************************************************************************/
 
777
/*       Execution functions                                             */
 
778
/*************************************************************************/
 
779
 
 
780
 
 
781
/*
 
782
 make_ch_symlink -
 
783
  
 
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.
 
788
 */
 
789
 
 
790
void make_ch_symlink()
 
791
{
 
792
        int i, flag,notdone;
 
793
 
 
794
        unlink(tempdirstr);
 
795
 
 
796
        /*find first unused channel*/
 
797
        i=0;
 
798
        flag = FALSE;
 
799
        notdone = TRUE;
 
800
 
 
801
        while ((i < sysdata->num_channels) && notdone) 
 
802
    {
 
803
                if (local_channels[i].free_channel)
 
804
                {
 
805
                        symlink(local_channels[i].comm_filename,tempdirstr);
 
806
                        local_channels[i].is_symlink = TRUE;
 
807
                        flag = TRUE;
 
808
                        notdone = FALSE;
 
809
                        sysdata->free_channel_index = i;
 
810
                }
 
811
                else
 
812
                {i++;}
 
813
    }
 
814
 
 
815
        if (flag)
 
816
    {
 
817
                Debug("MAKE_SYMLINK: made link to channel %d",i);  
 
818
    }
 
819
        else 
 
820
    { 
 
821
                sysdata->free_channel_index = -1;
 
822
                free_channels_flag = FALSE;
 
823
                Debug("MAKE_SYMLINK: All channels are in use."); 
 
824
    }
 
825
}
 
826
 
 
827
 
 
828
/* run_it debug functions */
 
829
void PrintData(char* str)
 
830
{
 
831
        Debug("%s  ready_count: %d  free_channel_index: %d",str,
 
832
                  sysdata->ready_count,sysdata->free_channel_index);
 
833
}
 
834
 
 
835
 
 
836
void PrintChannelSettings(local_channel * ch)
 
837
{
 
838
        printf("====================\n");
 
839
    printf("Current Channel Settings:\n");
 
840
        printf("    Comm Name:  %s\n",ch->comm_filename);
 
841
 
 
842
        if ((ch->channel_flags & CUE_FLAG) == CUE_FLAG)
 
843
                printf("    Cue  Name:  %s\n",ch->cue_filename);
 
844
 
 
845
    switch (ch->channel_type)
 
846
        {
 
847
                case PIPE_CHANNEL:   printf("    Type:       PIPE\n");break;
 
848
                case SOCKET_CHANNEL: printf("    Type:       SOCKET\n");break;
 
849
                default:             printf("    Type:       UNKNOWN\n");
 
850
        }
 
851
 
 
852
        switch (ch->cue)
 
853
        {
 
854
                case 0:  printf("    Cue?        NO\n"); break;
 
855
                default: printf("    Cue?        YES\n"); break;
 
856
        }
 
857
 
 
858
        switch (ch->free_channel)
 
859
        {
 
860
                case 0:  printf("    Free?       NO\n"); break;
 
861
                default: printf("    Free?       YES\n"); break;
 
862
        }
 
863
 
 
864
        switch (ch->is_symlink)
 
865
        {
 
866
                case 0:  printf("    Symlink?    NO\n"); break;
 
867
                default: printf("    Symlink?    YES\n");
 
868
        }
 
869
 
 
870
        printf("    Left Gain:  %d\n",ch->left_gain);
 
871
        printf("    Right Gain: %d\n",ch->right_gain);
 
872
 
 
873
        printf("====================\n");
 
874
}
 
875
 
 
876
 
 
877
signed short * add_main_audio(signed short * out_buf,local_channel ** buf_pointers, 
 
878
                                                          int channel_count)
 
879
{
 
880
        switch (channel_count)
 
881
        {
 
882
                case 0: return NULL;
 
883
                case 1:
 
884
                        memcpy(out_buf,buf_pointers[0]->buffer.buf,DB_BUFSIZE_CHAR);
 
885
                        return out_buf;
 
886
                        break;
 
887
                case 2: 
 
888
                        fs_add2channels(out_buf,&(buf_pointers[0]->buffer),
 
889
                                                        &(buf_pointers[1]->buffer));
 
890
                        return out_buf;
 
891
                        break;
 
892
                case 3: 
 
893
                        fs_add3channels(out_buf,&(buf_pointers[0]->buffer),
 
894
                                                        &(buf_pointers[1]->buffer),&(buf_pointers[2]->buffer));
 
895
                        return out_buf;
 
896
                        break;
 
897
                case 4: 
 
898
                        fs_add4channels(out_buf,      &(buf_pointers[0]->buffer),
 
899
                                                        &(buf_pointers[1]->buffer), &(buf_pointers[2]->buffer),
 
900
                                                        &(buf_pointers[3]->buffer));
 
901
                        return out_buf;
 
902
                        break;
 
903
                case 5: 
 
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));
 
907
                        return out_buf;
 
908
                        break;
 
909
                case 6: 
 
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));
 
914
                        return out_buf;
 
915
                        break;
 
916
                case 7: 
 
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));
 
921
                        return out_buf;
 
922
                        break;
 
923
                case 8: 
 
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));
 
929
                        return out_buf;
 
930
                        break;  
 
931
                default:
 
932
                        Error("add_main_audio: fs_addNchannels NOT IMPLEMENTED!!!!!!!!");
 
933
                        /* fs_addNchannels(out_buf,&(buf_pointers,sysdata->num_channels);*/
 
934
                        break;
 
935
        } /* end switch */
 
936
        
 
937
        return NULL;
 
938
}
 
939
 
 
940
 
 
941
 
 
942
signed short * add_cue_audio(signed short * out_buf,local_channel ** buf_pointers, 
 
943
                                                         int channel_count)
 
944
{
 
945
        switch (channel_count)
 
946
        {
 
947
                case 0: return NULL;
 
948
                case 1:
 
949
                        memcpy(out_buf,buf_pointers[0]->cue_buffer.buf,DB_BUFSIZE_CHAR);
 
950
                        return out_buf;
 
951
                        break;
 
952
                case 2: 
 
953
                        fs_add2channels(out_buf,
 
954
                                                        &(buf_pointers[0]->cue_buffer),
 
955
                                                        &(buf_pointers[1]->cue_buffer));
 
956
                        return out_buf;
 
957
                        break;
 
958
                case 3: 
 
959
                        fs_add3channels(out_buf,&(buf_pointers[0]->cue_buffer),
 
960
                                                        &(buf_pointers[1]->cue_buffer),&(buf_pointers[2]->cue_buffer));
 
961
                        return out_buf;
 
962
                        break;
 
963
                case 4: 
 
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));
 
967
                        return out_buf;
 
968
                        break;
 
969
                case 5: 
 
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));
 
973
                        return out_buf;
 
974
                        break;
 
975
                case 6: 
 
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));
 
980
                        return out_buf;
 
981
                        break;
 
982
                case 7: 
 
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));
 
987
                        return out_buf;
 
988
                        break;
 
989
                case 8: 
 
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));
 
995
                        return out_buf;
 
996
                        break;  
 
997
                default:
 
998
                        Error("add_cue_audio: fs_addNchannels NOT IMPLEMENTED!!!!!!!!");
 
999
                        /* fs_addNchannels(out_buf,buf_pointers,sysdata->num_channels);*/
 
1000
                        break;
 
1001
        } /* end switch */
 
1002
        
 
1003
        return NULL;
 
1004
}
 
1005
 
 
1006
 
 
1007
/*
 
1008
  run_it - executes the channel listener loop, applies Fourier Synthesis when
 
1009
           data is ready.
 
1010
 
 
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 
 
1016
                   artifacts remain.  
 
1017
 
 
1018
  inputs - the input channel pipes
 
1019
  outputs - the fourier synthesis of the pipes is sent to the soundcard.
 
1020
 */
 
1021
void run_it()
 
1022
{
 
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;
 
1030
 
 
1031
        static fd_set  temp_read_set;
 
1032
        static struct  timeval timeout;
 
1033
        static int     timeout_value_sec;
 
1034
        static int     timeout_value_usec;
 
1035
 
 
1036
        /* temp channel */
 
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;
 
1043
        static int     skipnum;
 
1044
 
 
1045
/*      static int loop_count = 0; */
 
1046
 
 
1047
        /* init local vars */
 
1048
        result = select_result = channel_count = cue_count = i = 0;
 
1049
        loop_flag = TRUE;
 
1050
        checknum = total_timeout_count = current_timeout_count = 0;
 
1051
  
 
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;
 
1054
  
 
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);       
 
1058
 
 
1059
        for (i = 0; i < sysdata->num_channels; i++)
 
1060
    {
 
1061
                buf_pointers[i] = NULL;
 
1062
    }
 
1063
  
 
1064
        free_channels_flag = TRUE;
 
1065
        make_ch_symlink();
 
1066
 
 
1067
        local_cue = FALSE;
 
1068
        pause_flag = 1;
 
1069
 
 
1070
        /* set initial timeout to be 5 seconds */
 
1071
        timeout_value_sec = MIN_TIMEOUT_VALUE_SEC;
 
1072
        timeout_value_usec = MIN_TIMEOUT_VALUE_USEC;
 
1073
 
 
1074
        while (loop_flag)
 
1075
    {
 
1076
                /* reset audio if necessary */
 
1077
                if (reset_audio_flag)
 
1078
                {
 
1079
                        reset_audio_flag = 0;
 
1080
 
 
1081
                        if (main_audio != NULL) 
 
1082
                        {
 
1083
                                close_audio(main_audio);
 
1084
                                main_audio = NULL;
 
1085
                        }
 
1086
                        
 
1087
                        Debug("Re-opening main audio device.");
 
1088
                        
 
1089
                        if ((main_audio = init_audio(sysdata->main_audio_device,O_WRONLY,stdout_flag,
 
1090
                                                                                 sysdata->num_main_buffs)) == NULL)
 
1091
                        {
 
1092
                                Error("Could not open main audio device.");
 
1093
                        }
 
1094
                        
 
1095
                        if (cue_flag)
 
1096
                        {
 
1097
                                Debug("Re-opening cue audio device...");
 
1098
                                
 
1099
                                if (cue_audio != NULL) 
 
1100
                                {
 
1101
                                        close_audio(cue_audio);
 
1102
                                        cue_audio = NULL;
 
1103
                                }
 
1104
                                
 
1105
                                if ((cue_audio = init_audio(sysdata->cue_audio_device,
 
1106
                                                                                        O_WRONLY/*  | O_NONBLOCK */,
 
1107
                                                                                        stdout_flag,sysdata->num_cue_buffs)) == NULL)
 
1108
                                {
 
1109
                                        Error("Could not open cue audio device.");
 
1110
                                }
 
1111
                        }
 
1112
                        
 
1113
                        Debug("Audio is reset.");
 
1114
                }
 
1115
 
 
1116
                /*******  Handle IO *******/
 
1117
 
 
1118
                /* reset file descriptor set */
 
1119
                FD_ZERO(&temp_read_set);
 
1120
                temp_read_set = read_ch_set;
 
1121
 
 
1122
                /* reset temp_buf_pointer and channel pointer */
 
1123
                temp_buf_pointers = buf_pointers;
 
1124
                temp_cue_pointers = cue_pointers;
 
1125
 
 
1126
                temp_ch = local_channels; 
 
1127
                temp_cue = local_channels;
 
1128
                temp_buf = NULL;
 
1129
      
 
1130
                channel_count = cue_count = 0;
 
1131
      
 
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. */      
 
1135
 
 
1136
                timeout.tv_sec = timeout_value_sec;
 
1137
                timeout.tv_usec = timeout_value_usec;
 
1138
 
 
1139
                select_result = select(numch,&temp_read_set,(fd_set*) 0,(fd_set*) 0, &timeout);
 
1140
      
 
1141
                /* verify that all pipes have enough data in them */
 
1142
                if (select_result > 0)
 
1143
                {
 
1144
                        skipnum = 0;
 
1145
                        pause_flag = 1;
 
1146
                        timeout_value_sec = MIN_TIMEOUT_VALUE_SEC;
 
1147
                        timeout_value_usec = MIN_TIMEOUT_VALUE_USEC;
 
1148
 
 
1149
                        /* set through channels and see if data is ready */
 
1150
                        for (i=0; i < sysdata->num_channels;i++)
 
1151
                        {
 
1152
                                if (FD_ISSET(temp_ch->server_comm_fd,&temp_read_set))
 
1153
                                {
 
1154
                                        /* get amount of data in the buffer */
 
1155
                                        if (ioctl(temp_ch->server_comm_fd,FIONREAD,&result) != 0)
 
1156
                                        {
 
1157
                                                perror("FIONREAD FAILED!!!  ");
 
1158
                                        }
 
1159
                                        else
 
1160
                                        {
 
1161
                                                if (result < DB_BUFSIZE_CHAR)
 
1162
                                                {
 
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 */
 
1166
                                                        int usec = 5000;
 
1167
                                                        struct timeval tv;
 
1168
 
 
1169
                                                        temp_ch->skip_count++;
 
1170
                                                        
 
1171
                                                        tv.tv_sec = usec / 1000000;
 
1172
                                                        usec -= tv.tv_sec * 1000000;
 
1173
                                                        tv.tv_usec = usec;
 
1174
                                                        select(0, NULL, NULL, NULL, &tv);
 
1175
 
 
1176
                                                        /* force the for loop to exit to minimize sleeps */
 
1177
                                                        i = sysdata->num_channels;
 
1178
                                                                                                                
 
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++;
 
1183
                                                }
 
1184
                                        }
 
1185
                                }
 
1186
                                
 
1187
                                temp_ch++;
 
1188
                        }
 
1189
 
 
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;
 
1193
 
 
1194
                        temp_ch = local_channels;
 
1195
 
 
1196
                        /* check each channel to see if data is ready */ 
 
1197
                        for (i=0; i < sysdata->num_channels;i++)
 
1198
                        {
 
1199
                                /* grab cue value for use inside the critical section */
 
1200
                                local_cue = temp_ch->cue;
 
1201
 
 
1202
                                if (FD_ISSET(temp_ch->server_comm_fd,&temp_read_set))
 
1203
                                {
 
1204
                                        switch (temp_ch->channel_type)
 
1205
                                        {
 
1206
                                                case PIPE_CHANNEL:
 
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,
 
1210
                                                                                  DB_BUFSIZE_CHAR);
 
1211
                                                        temp_buf->len = result;
 
1212
                                                        temp_ch->skip_count = 0;
 
1213
                                                        break;
 
1214
                                                case SOCKET_CHANNEL:
 
1215
                                                        Error("Socket channels not yet implemented.");
 
1216
                                                        break;
 
1217
                                                default:
 
1218
                                                        Error("Unknown channel type.");
 
1219
                                                        break;
 
1220
                                        }
 
1221
 
 
1222
                                        /* if we read data, then add it to the buffer array */
 
1223
                                        if (result > 0)
 
1224
                                        {
 
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;
 
1229
                                                
 
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)
 
1234
                                                {
 
1235
                                                        if (Check_Debug())
 
1236
                                                        {
 
1237
                                                                Debug("New data on %s",temp_ch->comm_filename);
 
1238
                                                                PrintChannelSettings(temp_ch);
 
1239
                                                        }
 
1240
                                                        temp_ch->is_symlink = FALSE;
 
1241
                                                        temp_ch->free_channel = FALSE;
 
1242
                                                        make_ch_symlink();
 
1243
 
 
1244
                                                        /* clear cue buffer data for synch.*/
 
1245
                                                        if (cue_flag)
 
1246
                                                        {
 
1247
                                                                if (local_cue)
 
1248
                                                                {
 
1249
                                                                        result = read(temp_ch->server_cue_fd,temp_buf->buf,
 
1250
                                                                                                  DB_BUFSIZE_CHAR);
 
1251
                                                                }
 
1252
                                                        }
 
1253
                                                }
 
1254
                                                else
 
1255
                                                {
 
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*/
 
1259
                                                        if (checknum)
 
1260
                                                        { 
 
1261
                                                                Debug("cleared %d bytes",checknum);
 
1262
                                                                /* divide by two since buf is signed shorts which are 2 bytes long */
 
1263
 
 
1264
                                                                memset(temp_buf->buf + (temp_buf->len / 
 
1265
                                                                                                                sizeof(signed short)),0,checknum);
 
1266
                                                        }
 
1267
                                                        
 
1268
                                                        /* keep a pointer to the buffer that has data_ready */
 
1269
                                                        temp_buf_pointers[channel_count] = temp_ch;
 
1270
                                                        channel_count++;
 
1271
                                                        
 
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)
 
1276
                                                        {
 
1277
                                                                temp_buf = &(temp_ch->cue_buffer);
 
1278
                                                                result = read(temp_ch->server_cue_fd,temp_buf->buf,
 
1279
                                                                                          DB_BUFSIZE_CHAR);
 
1280
                                                                
 
1281
                                                                if (result > 0)
 
1282
                                                                {                                                                       
 
1283
                                                                        temp_buf->len = result;
 
1284
                                                                        temp_buf->data_ready = TRUE;
 
1285
                                                                        
 
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*/
 
1289
                                                                        if (checknum)
 
1290
                                                                        {
 
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);
 
1294
                                                                        }
 
1295
                                                                        
 
1296
                                                                        /* keep a pointer to the buffer that has data_ready */
 
1297
                                                                        temp_cue_pointers[cue_count] = temp_ch;
 
1298
                                                                        cue_count++;
 
1299
                                                                } /* end if result > 0 */
 
1300
                                                                
 
1301
                                                        }  /* end cue_flag */
 
1302
                                                }
 
1303
                                        }  /*end if result */
 
1304
                                        else 
 
1305
                                        {
 
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);
 
1308
                      
 
1309
                                                FD_CLR(temp_ch->server_comm_fd,&read_ch_set);
 
1310
 
 
1311
                                                reset_channel(temp_ch,TRUE);
 
1312
 
 
1313
                                                /*check the symlink*/
 
1314
                                                if (!free_channels_flag)
 
1315
                                                {
 
1316
                                                        Debug("Channels in use is now less than Maximum.");
 
1317
                                                        free_channels_flag = TRUE;
 
1318
                                                        make_ch_symlink();
 
1319
                                                }
 
1320
                                        }
 
1321
                                }        /*end fd_set check*/
 
1322
 
 
1323
                                temp_ch++;
 
1324
                        }  /*end for*/
 
1325
                        
 
1326
                        /*write main channel data*/                     
 
1327
                        if (add_main_audio(output_buf,buf_pointers,channel_count) != NULL)
 
1328
                        {
 
1329
                                /*write cue data*/
 
1330
                                if (cue_flag)
 
1331
                                {
 
1332
                                        if (add_cue_audio(cue_output_buf,cue_pointers,cue_count) != NULL)
 
1333
                                        {
 
1334
                                                /* handle cue split */
 
1335
                                                if (sysdata->cue_split)
 
1336
                                                {
 
1337
                                                        int  tempval, tempval2;
 
1338
                                                        short * tempout, *tempout2;
 
1339
                                                        int i;
 
1340
 
 
1341
                                                        tempout = (short *) output_buf;
 
1342
                                                        tempout2 = (short *) cue_output_buf;
 
1343
 
 
1344
                                                        tempout = output_buf;
 
1345
                                                        tempout2 = cue_output_buf;
 
1346
                                                        
 
1347
                                                        for(i = 0; i < DB_BUFSIZE_SHORT/2; i++)
 
1348
                                                        {
 
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])));
 
1353
                                                                
 
1354
                                                                if(tempval > 32767) {tempval = 32767;}
 
1355
                                                                if(tempval < -32688) {tempval = -32767;}
 
1356
                                                                if(tempval2 > 32767) {tempval2 = 32767;}
 
1357
                                                                if(tempval2 < -32688) {tempval2 = -32767;}
 
1358
 
 
1359
                                                                /* add to cue buffer */
 
1360
                                                                *tempout2 = (short)tempval;
 
1361
                                                                tempout2++;
 
1362
                                                                *tempout2 = (short)tempval2;
 
1363
                                                                tempout2++;
 
1364
                                                                
 
1365
                                                                tempout++;
 
1366
                                                                tempout++;
 
1367
                                                        }
 
1368
                                                }
 
1369
                                                
 
1370
                                                if (single_output_flag)
 
1371
                                                {
 
1372
                                                        memcpy(output_buf,cue_output_buf,DB_BUFSIZE_CHAR);
 
1373
                                                }
 
1374
                                                else
 
1375
                                                {
 
1376
                                                        if (write_audio(cue_audio,cue_output_buf,DB_BUFSIZE_CHAR) <= 0)
 
1377
                                                        {
 
1378
                                                                perror("error outputing cue data ");
 
1379
                                                        }
 
1380
                                                }
 
1381
                                        }
 
1382
                                        else /* add_cue_audio */
 
1383
                                        {
 
1384
                                                if (single_output_flag)
 
1385
                                                {
 
1386
                                                        /* create mono output of master and set cue to zero */
 
1387
 
 
1388
                                                        int  tempval, tempval2;
 
1389
                                                        short * tempout, *tempout2;
 
1390
                                                        int i;
 
1391
 
 
1392
                                                        tempout = (short *) output_buf;
 
1393
                                                        tempout2 = (short *) cue_output_buf;
 
1394
 
 
1395
                                                        tempout = output_buf;
 
1396
                                                        tempout2 = cue_output_buf;
 
1397
                                                        
 
1398
                                                        for(i = 0; i < DB_BUFSIZE_SHORT/2; i++)
 
1399
                                                        {
 
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])));
 
1404
                                                                
 
1405
                                                                if(tempval > 32767) {tempval = 32767;}
 
1406
                                                                if(tempval < -32688) {tempval = -32767;}
 
1407
                                                                if(tempval2 > 32767) {tempval2 = 32767;}
 
1408
                                                                if(tempval2 < -32688) {tempval2 = -32767;}
 
1409
 
 
1410
                                                                /* add to cue buffer */
 
1411
                                                                *tempout = (short)tempval;
 
1412
                                                                tempout++;
 
1413
                                                                *tempout = (short)0;
 
1414
                                                                tempout++;
 
1415
                                                                
 
1416
                                                                tempout2++;
 
1417
                                                                tempout2++;
 
1418
                                                        }
 
1419
                                                }
 
1420
                                                else
 
1421
                                                {
 
1422
                                                        write_audio(cue_audio,empty_buf,DB_BUFSIZE_CHAR);
 
1423
                                                }
 
1424
/*                                              memset(cue_output_buf,0,DB_BUFSIZE_CHAR); */
 
1425
                                        } /* add cue audio */
 
1426
                                }  /* end write cue data */
 
1427
 
 
1428
                                if (write_audio(main_audio,output_buf,DB_BUFSIZE_CHAR) <= 0)
 
1429
                                {
 
1430
                                        perror("error outputing main data ");
 
1431
                                }
 
1432
 
 
1433
                                /* if we are recording, write data to file */
 
1434
                                if (record_fid != NULL)
 
1435
                                {
 
1436
                                        /* make sure there is space in the file, Max is ~4GB */
 
1437
                                        if (record_count < (MAX_WAV_LENGTH - DB_BUFSIZE_CHAR))
 
1438
                                        {
 
1439
                                                record_count += fwrite(output_buf,1,DB_BUFSIZE_CHAR,record_fid);
 
1440
                                        }
 
1441
                                        else
 
1442
                                        {
 
1443
                                                /* out of space, stop recording */
 
1444
                                                raise(SIGUSR2);
 
1445
                                                Error("DBFSD: ran out of space while recording output.");
 
1446
                                        }
 
1447
                                }
 
1448
 
 
1449
                        } /* add_main_audio */
 
1450
                }  /*end if select_result*/
 
1451
                else 
 
1452
                {
 
1453
                        if (select_result == 0)
 
1454
                        {
 
1455
                                Debug("Timeout total: %d  since last sample: %d (minutes)",total_timeout_count,current_timeout_count);
 
1456
                                total_timeout_count++;
 
1457
                                current_timeout_count++;
 
1458
 
 
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;
 
1462
 
 
1463
                                if (pause_flag)
 
1464
                                {
 
1465
                                        Debug("Pausing main audio...");
 
1466
                                        pause_audio(main_audio);
 
1467
                                        
 
1468
                                        if (cue_flag)
 
1469
                                        {
 
1470
                                                Debug("Pausing cue audio...");
 
1471
                                                pause_audio(cue_audio);
 
1472
                                        }
 
1473
 
 
1474
                                        pause_flag = 0;
 
1475
                                }
 
1476
                        }
 
1477
 
 
1478
                        /*received an error on select, check which one it is.*/
 
1479
                        if (select_result == -1)
 
1480
                        {
 
1481
                                switch (errno)
 
1482
                                {
 
1483
                                        case EBADF:
 
1484
                                                Error("EBADF: invalid descriptors for select.\n");
 
1485
                                                break;
 
1486
                                        case EINTR:
 
1487
                                                Debug("EINTR: select returned due to interrupt.\n");
 
1488
                                                break;
 
1489
                                        case EINVAL:
 
1490
                                                Error("EINVAL: invalid parameters to select.\n");
 
1491
                                                break;
 
1492
                                        default: Error("Unknown error on select.\n"); break;
 
1493
                                }
 
1494
                        } /*end if select_result*/
 
1495
                }  /*end else*/
 
1496
        } /* end while */
 
1497
}
 
1498
 
 
1499
 
 
1500
 
 
1501
/***************************************************************************/
 
1502
/*                              MAIN                                       */
 
1503
/***************************************************************************/
 
1504
 
 
1505
int main (int argc, char *argv[])
 
1506
{
 
1507
        /*daemon init's*/
 
1508
#ifdef DBMIX_DEBUG
 
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");
 
1510
#endif
 
1511
 
 
1512
        sysdata = NULL;
 
1513
        local_channels = NULL;
 
1514
 
 
1515
        init_sysdata();
 
1516
        Debug("sysdata allocated.");
 
1517
        parse_cmdline(argc,argv);
 
1518
 
 
1519
        Debug("cmdline parsed.");
 
1520
        Debug("pid is: %d\n",sysdata->pid);
 
1521
 
 
1522
        Debug("Begining initialization...\n");
 
1523
 
 
1524
        /*init audio, this *must* be done before the call to init_channels*/
 
1525
 
 
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);
 
1530
                
 
1531
        main_audio = cue_audio = NULL;
 
1532
 
 
1533
        if ((main_audio = init_audio(sysdata->main_audio_device,O_WRONLY,stdout_flag,
 
1534
                                                                 sysdata->num_main_buffs)) == NULL)
 
1535
        {
 
1536
                Error("Could not open main audio device.");
 
1537
                return -1;
 
1538
        }
 
1539
        
 
1540
        if (single_output_flag)
 
1541
        {
 
1542
                Debug("WARNING!!! Cue will be output as a channel of the master output!!!!\n");
 
1543
                cue_audio = NULL;
 
1544
        }
 
1545
        else
 
1546
        {
 
1547
                if (cue_flag)
 
1548
                {
 
1549
                        Debug("Opening cue audio device...");
 
1550
                        
 
1551
                        if ((cue_audio = init_audio(sysdata->cue_audio_device,
 
1552
                                                                                O_WRONLY/*  | O_NONBLOCK */,
 
1553
                                                                                0,sysdata->num_cue_buffs)) == NULL)
 
1554
                        {
 
1555
                                Error("Could not open cue audio device.");
 
1556
                                return -1;
 
1557
                        }
 
1558
                }
 
1559
        }
 
1560
 
 
1561
        Debug("audio initialized.");
 
1562
 
 
1563
        if (init_channels() != SUCCESS)
 
1564
        {shutdown_dbfsd(); return -1;}
 
1565
 
 
1566
        Debug("channels initialized.");
 
1567
  
 
1568
  /*install signal handlers*/
 
1569
        reset_audio_flag = 0;
 
1570
 
 
1571
        signal(SIGINT,sigexit);
 
1572
        signal(SIGTERM,sigexit);
 
1573
        signal(SIGCONT,sigcont);
 
1574
        signal(SIGHUP,sighup);
 
1575
        signal(SIGUSR1,sigusr1);
 
1576
        signal(SIGUSR2,sigusr2);
 
1577
 
 
1578
        Debug("Initialization complete... running... \n");
 
1579
  
 
1580
        run_it();
 
1581
 
 
1582
        Debug("Run_it complete.");
 
1583
 
 
1584
        shutdown_dbfsd();
 
1585
 
 
1586
        return 0;
 
1587
}
 
1588
 
 
1589
 
 
1590
 
 
1591
 
 
1592
 
 
1593