Recognizes if input is ogg or not.
[xiph.git] / postfish / output.c
blob3d0e73497a2072a4f32ea19d6600c31d7bb2bdba
1 /*
3 * postfish
4 *
5 * Copyright (C) 2002-2005 Monty
7 * Postfish is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
12 * Postfish is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Postfish; see the file COPYING. If not, write to the
19 * Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* sound playback code is OSS-specific for now */
25 #include <linux/soundcard.h>
26 #include <sys/ioctl.h>
27 #include "postfish.h"
28 #include "feedback.h"
29 #include "input.h"
30 #include "output.h"
31 #include "declip.h"
32 #include "eq.h"
33 #include "multicompand.h"
34 #include "singlecomp.h"
35 #include "deverb.h"
36 #include "limit.h"
37 #include "mute.h"
38 #include "mix.h"
39 #include "freeverb.h"
41 output_settings outset;
43 extern int input_size;
44 extern int input_rate;
45 sig_atomic_t playback_active=0;
46 sig_atomic_t playback_exit=0;
47 sig_atomic_t playback_seeking=0;
48 sig_atomic_t master_att;
50 void output_reset(void){
51 /* empty feedback queues */
52 while(pull_output_feedback(NULL,NULL));
53 return;
56 void pipeline_reset(){
57 int flags=fcntl(eventpipe[0],F_GETFL);
58 char buf[1];
59 /* drain the event pipe */
60 if(fcntl(eventpipe[0],F_SETFL,O_NONBLOCK))
61 fprintf(stderr,"Unable to set O_NONBLOCK on event pipe.\n");
62 while(read(eventpipe[0],buf,1)>0);
63 fcntl(eventpipe[0],F_SETFL,flags);
65 input_reset(); /* clear any persistent lapping state */
66 declip_reset(); /* clear any persistent lapping state */
67 eq_reset(); /* clear any persistent lapping state */
68 multicompand_reset(); /* clear any persistent lapping state */
69 singlecomp_reset(); /* clear any persistent lapping state */
70 deverb_reset(); /* clear any persistent lapping state */
71 limit_reset(); /* clear any persistent lapping state */
72 output_reset(); /* clear any persistent lapping state */
73 mix_reset();
74 p_reverb_reset();
77 typedef struct output_feedback{
78 feedback_generic parent_class;
79 float *rms;
80 float *peak;
81 } output_feedback;
83 static feedback_generic_pool feedpool;
85 static feedback_generic *new_output_feedback(void){
86 output_feedback *ret=malloc(sizeof(*ret));
87 ret->rms=malloc(OUTPUT_CHANNELS*sizeof(*ret->rms));
88 ret->peak=malloc(OUTPUT_CHANNELS*sizeof(*ret->peak));
89 return (feedback_generic *)ret;
92 static void push_output_feedback(float *peak,float *rms){
93 output_feedback *f=(output_feedback *)
94 feedback_new(&feedpool,new_output_feedback);
96 memcpy(f->rms,rms,OUTPUT_CHANNELS*sizeof(*rms));
97 memcpy(f->peak,peak,OUTPUT_CHANNELS*sizeof(*peak));
98 feedback_push(&feedpool,(feedback_generic *)f);
101 int pull_output_feedback(float *peak,float *rms){
102 output_feedback *f=(output_feedback *)feedback_pull(&feedpool);
103 if(!f)return 0;
104 if(rms)memcpy(rms,f->rms,sizeof(*rms)*OUTPUT_CHANNELS);
105 if(peak)memcpy(peak,f->peak,sizeof(*peak)*OUTPUT_CHANNELS);
106 feedback_old(&feedpool,(feedback_generic *)f);
107 return 1;
110 int output_feedback_deep(void){
111 return feedback_deep(&feedpool);
114 static void PutNumLE(long num,FILE *f,int bytes){
115 int i=0;
116 while(bytes--){
117 fputc((num>>(i<<3))&0xff,f);
118 i++;
122 static void PutNumBE(long num,FILE *f,int bytes){
123 switch(bytes){
124 case 4:
125 fputc((num>>24)&0xff,f);
126 case 3:
127 fputc((num>>16)&0xff,f);
128 case 2:
129 fputc((num>>8)&0xff,f);
130 case 1:
131 fputc(num&0xff,f);
135 /* Borrowed from sox */
136 # define FloatToUnsigned(f) ((u_int32_t)(((int32_t)(f - 2147483648.0)) + 2147483647L) + 1)
137 static void ConvertToIeeeExtended(double num, char *bytes){
138 int sign;
139 int expon;
140 double fMant, fsMant;
141 u_int32_t hiMant, loMant;
143 if (num < 0) {
144 sign = 0x8000;
145 num *= -1;
146 } else {
147 sign = 0;
150 if (num == 0) {
151 expon = 0; hiMant = 0; loMant = 0;
153 else {
154 fMant = frexp(num, &expon);
155 if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */
156 expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
158 else { /* Finite */
159 expon += 16382;
160 if (expon < 0) { /* denormalized */
161 fMant = ldexp(fMant, expon);
162 expon = 0;
164 expon |= sign;
165 fMant = ldexp(fMant, 32);
166 fsMant = floor(fMant);
167 hiMant = FloatToUnsigned(fsMant);
168 fMant = ldexp(fMant - fsMant, 32);
169 fsMant = floor(fMant);
170 loMant = FloatToUnsigned(fsMant);
174 bytes[0] = expon >> 8;
175 bytes[1] = expon;
176 bytes[2] = hiMant >> 24;
177 bytes[3] = hiMant >> 16;
178 bytes[4] = hiMant >> 8;
179 bytes[5] = hiMant;
180 bytes[6] = loMant >> 24;
181 bytes[7] = loMant >> 16;
182 bytes[8] = loMant >> 8;
183 bytes[9] = loMant;
186 static void WriteWav(FILE *f,long channels,long rate,long bits,long duration){
187 if(ftell(f)>0)
188 if(fseek(f,0,SEEK_SET))
189 return;
190 fprintf(f,"RIFF");
191 PutNumLE(duration+44-8,f,4);
192 fprintf(f,"WAVEfmt ");
193 PutNumLE(16,f,4);
194 PutNumLE(1,f,2);
195 PutNumLE(channels,f,2);
196 PutNumLE(rate,f,4);
197 PutNumLE(rate*channels*((bits-1)/8+1),f,4);
198 PutNumLE(((bits-1)/8+1)*channels,f,2);
199 PutNumLE(bits,f,2);
200 fprintf(f,"data");
201 PutNumLE(duration,f,4);
204 void WriteAifc(FILE *f,long channels,long rate,long bits,long duration){
205 int bytes=(bits+7)/8;
206 long size=duration+86;
207 long frames=duration/bytes/channels;
208 char ieee[10];
210 if(ftell(f)>0)
211 if(fseek(f,0,SEEK_SET))
212 return;
214 /* Again, quick and dirty */
216 fprintf(f,"FORM");
217 if(duration>0)
218 PutNumBE(size-8,f,4);
219 else
220 PutNumBE(0,f,4);
221 fprintf(f,"AIFC");
222 fprintf(f,"FVER");
223 PutNumBE(4,f,4);
224 PutNumBE(2726318400UL,f,4);
226 fprintf(f,"COMM");
227 PutNumBE(38,f,4);
228 PutNumBE(channels,f,2);
229 if(duration>0)
230 PutNumBE(frames,f,4);
231 else
232 PutNumBE(-1,f,4);
234 PutNumBE(bits,f,2);
235 ConvertToIeeeExtended(rate,ieee);
236 fwrite(ieee,1,10,f);
238 fprintf(f,"NONE");
239 PutNumBE(14,f,1);
240 fprintf(f,"not compressed");
241 PutNumBE(0,f,1);
243 fprintf(f,"SSND");
244 if(duration>0)
245 PutNumBE(duration+8,f,4);
246 else
247 PutNumBE(0,f,4);
249 PutNumBE(0,f,4);
250 PutNumBE(0,f,4);
254 static int isachr(int f){
255 struct stat s;
257 if(!fstat(f,&s))
258 if(S_ISCHR(s.st_mode)) return 1;
259 return 0;
262 static int isareg(int f){
263 struct stat s;
265 if(!fstat(f,&s))
266 if(S_ISREG(s.st_mode)) return 1;
267 return 0;
270 static int ilog(long x){
271 int ret=-1;
273 while(x>0){
274 x>>=1;
275 ret++;
277 return ret;
280 static int is_oss(int f){
281 struct stat s;
283 if(isachr(f))
284 if(!fstat(f,&s)){
285 int major=(int)(s.st_rdev>>8)&0xff;
286 int minor=(int)(s.st_rdev&0xff);
288 // is this a Linux OSS audio device (Major 14) ?
289 if(major==14 && ((minor&0xf)==3 || (minor&0xf)==4))return 1;
292 return 0;
295 static int is_alsa(int f){
296 struct stat s;
298 if(isachr(f))
299 if(!fstat(f,&s)){
300 int type=(int)(s.st_rdev>>8);
302 // is this a Linux ALSA audio device (Major 116) ?
303 if(type==116)return 1;
306 return 0;
309 static int isaudio(int outfileno){
310 if(is_oss(outfileno))return 1;
311 if(is_alsa(outfileno))return 2;
312 return 0;
315 int output_stdout_available=0;
316 int output_stdout_device=0; /* 0== file, 1==OSS, 2==ALSA */
317 int output_monitor_available=0;
319 int output_probe_stdout(int outfileno){
320 int ret;
322 if(isatty(outfileno)){
323 /* stdout is the terminal; disable stdout */
324 output_stdout_available=0;
326 }else if (isareg(outfileno)){
327 /* stdout is a regular file */
328 output_stdout_available=1;
329 output_stdout_device=0;
331 }else if((ret=isaudio(outfileno))){
332 /* stdout is an audio device */
334 output_stdout_available=1;
335 output_stdout_device=ret;
337 if(ret==2){
338 fprintf(stderr,
339 "\nStdout is pointing to an ALSA sound device;\n"
340 "Postfish does not yet support ALSA playback.\n\n");
341 exit(1);
343 }else{
344 /* God only knows what stdout is. It might be /dev/null or some other.... treat it similar to file */
346 output_stdout_available=1;
347 output_stdout_device=0;
351 return 0;
354 #include <sys/types.h>
355 #include <sys/stat.h>
356 #include <dirent.h>
357 output_monitor_entry *monitor_list;
358 int monitor_entries;
360 static char *audio_dev_type[]={"file","OSS"};
362 /* look for sound devices that actually exist */
364 static void add_monitor(char *file, char *name,int type){
365 monitor_entries++;
366 if(monitor_list){
367 monitor_list=realloc(monitor_list,
368 monitor_entries*sizeof(*monitor_list));
369 }else
370 monitor_list=malloc(monitor_entries*sizeof(*monitor_list));
372 monitor_list[monitor_entries-1].file=strdup(file);
373 monitor_list[monitor_entries-1].name=strdup(name);
374 monitor_list[monitor_entries-1].type=type;
376 fprintf(stderr,"Found an output device (type %s): %s\n",
377 audio_dev_type[type],file);
380 static void output_probe_monitor_OSS(){
381 /* open /dev and search of major 14 */
382 DIR *d=opendir("/dev");
383 struct dirent *de;
385 if(d==NULL){
386 fprintf(stderr,"Odd; could not open /dev to look for audio devices.\n");
387 return;
390 while((de=readdir(d))){
391 struct stat s;
392 char buf[PATH_MAX];
393 snprintf(buf,PATH_MAX,"/dev/%s",de->d_name);
394 if(!stat(buf,&s)){
396 int major=(int)(s.st_rdev>>8)&0xff;
397 int minor=(int)(s.st_rdev&0xff);
399 // is this a Linux OSS dsp audio device (Major 14, minor 3,19,35...) ?
400 if(major==14 && (minor&0xf)==3){
401 int f=open(buf,O_RDWR|O_NONBLOCK);
402 if(f!=-1){
403 add_monitor(buf,de->d_name,1);
404 close(f);
410 closedir(d);
413 static int moncomp(const void *a, const void *b){
414 output_monitor_entry *ma=(output_monitor_entry *)a;
415 output_monitor_entry *mb=(output_monitor_entry *)b;
416 return(strcmp(ma->name,mb->name));
419 int output_probe_monitor(void ){
420 if(output_stdout_device!=0){
421 output_monitor_available=0;
422 return 0;
425 output_probe_monitor_OSS();
427 if(monitor_entries>0){
428 output_monitor_available=1;
430 /* sort the entries alphabetically by name */
431 qsort(monitor_list, monitor_entries, sizeof(*monitor_list), moncomp);
434 return 0;
437 #ifndef AFMT_S24_LE
438 # define AFMT_S24_LE 0x00000800
439 # define AFMT_S24_BE 0x00001000
440 # define AFMT_U24_LE 0x00002000
441 # define AFMT_U24_BE 0x00004000
442 #endif
444 static int OSS_playback_startup(FILE *f, int rate, int *ch, int *endian, int *bits,int *signp){
445 int fd=fileno(f);
446 int downgrade=0;
447 int failflag=1;
448 int local_ch=*ch;
449 int local_bits=*bits;
451 *endian=(AFMT_S16_NE==AFMT_S16_BE?1:0);
453 /* try to configure requested playback. If it fails, keep dropping back
454 until one works */
455 while(local_ch || local_bits>16){
456 int format;
458 switch(local_bits){
459 case 8:
460 format=AFMT_U8;
461 *signp=0;
462 break;
463 case 16:
464 format=AFMT_S16_NE;
465 *signp=1;
466 break;
467 case 24:
468 format=AFMT_S24_LE;
469 if(*endian)format=AFMT_S24_BE;
470 *signp=1;
471 break;
474 /* try to lower the DSP delay; this ioctl may fail gracefully */
477 long bytesperframe=(local_bits+7)/8*local_ch*input_size;
478 int fraglog=ilog(bytesperframe);
479 int fragment=0x00040000|fraglog,fragcheck;
481 fragcheck=fragment;
482 int ret=ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&fragment);
483 if(ret || fragcheck!=fragment){
484 fprintf(stderr,"Could not set DSP fragment size; continuing.\n");
488 /* format, channels, rate */
490 int temp=format;
491 int ret=ioctl(fd,SNDCTL_DSP_SETFMT,&temp);
492 if(ret || format!=temp) goto failset;
496 int temp=local_ch;
497 int ret=ioctl(fd,SNDCTL_DSP_CHANNELS,&temp);
498 if(ret || temp!=local_ch) goto failset;
502 int temp=rate;
503 int ret=ioctl(fd,SNDCTL_DSP_SPEED,&temp);
504 if(ret || temp!=rate) goto failset;
507 failflag=0;
508 break;
510 failset:
511 downgrade=1;
513 /* first try decreasing bit depth */
514 if(local_bits==24){
515 local_bits=16;
516 }else{
518 /* next, drop channels */
519 local_bits=*bits;
520 local_ch--;
523 ioctl(fd,SNDCTL_DSP_RESET);
526 if(failflag || downgrade)
527 fprintf(stderr,"Unable to set playback for %d bits, %d channels, %dHz\n",
528 *bits,*ch,rate);
529 if(downgrade && !failflag)
530 fprintf(stderr,"\tUsing %d bits, %d channels, %dHz instead\n",
531 local_bits,local_ch,rate);
532 if(failflag)return -1;
534 *bits=local_bits;
535 *ch=local_ch;
537 return 0;
540 static int output_startup(FILE *f, int devtype, int format, int rate, int *ch, int *endian, int *bits,int *signp){
541 switch(devtype){
542 case 0: // pipe, regular file or file device
543 switch(format){
544 case 0:
545 /* WAVE format */
546 ftruncate(fileno(f),0);
547 WriteWav(f,*ch,rate,*bits,-1);
548 *endian=0;
549 *signp=1;
550 if(*bits==8)*signp=0;
551 break;
552 case 1:
553 /* AIFF-C format */
554 ftruncate(fileno(f),0);
555 WriteAifc(f,*ch,rate,*bits,-1);
556 *endian=1;
557 *signp=1;
558 break;
559 case 2:
560 /* raw little endian */
561 *endian=0;
562 *signp=1;
563 if(*bits==8)*signp=0;
564 break;
565 case 3:
566 /* raw big endian */
567 *endian=1;
568 *signp=1;
569 if(*bits==8)*signp=0;
570 break;
571 default:
572 fprintf(stderr,"Unsupported output file format selected!\n");
573 return -1;
575 return 0;
577 case 1: // OSS playback
578 return OSS_playback_startup(f, rate, ch, endian, bits, signp);
580 default: // undefined for now
581 fprintf(stderr,"Unsupported playback device selected\n");
582 return -1;
586 static void output_halt(FILE *f,int devtype,int format, int rate, int ch, int endian, int bits,int signp,
587 off_t bytecount){
588 switch(devtype){
589 case 0:
590 switch(format){
591 case 0:
592 WriteWav(f,ch,rate,bits,bytecount); // will complete header only if stream is seekable
593 break;
594 case 1:
595 WriteAifc(f,ch,rate,bits,bytecount); // will complete header only if stream is seekable
596 break;
598 break;
599 case 1: // OSS
601 int fd=fileno(f);
602 ioctl(fd,SNDCTL_DSP_RESET);
607 static int outpack(time_linkage *link,unsigned char *audiobuf,
608 int ch,int bits,int endian,
609 int signp,int *source){
610 int bytes=(bits+7)>>3;
611 int32_t signxor=(signp?0:0x800000L);
612 int bytestep=bytes*(ch-1);
614 int endbytecase=endian*3+(bytes-1);
615 int j,i;
616 for(j=0;j<ch;j++){
617 unsigned char *o=audiobuf+bytes*j;
618 if(!mute_channel_muted(link->active,j) && source[j]){
620 float *d=link->data[j];
622 for(i=0;i<link->samples;i++){
623 float dval=d[i];
624 int32_t val=rint(dval*8388608.);
625 if(val>8388607)val=8388607;
626 if(val<-8388608)val=-8388608;
627 val ^= signxor;
629 switch(endbytecase){
630 case 2:
631 /* LE 24 */
632 *o++=val;
633 // fall through
634 case 1:
635 /* LE 16 */
636 *o++=val>>8;
637 // fall through
638 case 0:case 3:
639 /* 8 */
640 *o++=val>>16;
641 break;
642 case 4:
643 /* BE 16 */
644 *o++=val>>16;
645 *o++=val>>8;
646 break;
647 case 5:
648 /* BE 24 */
649 *o++=val>>16;
650 *o++=val>>8;
651 *o++=val;
652 break;
655 o+=bytestep;
657 }else{
658 for(i=0;i<link->samples;i++){
659 int32_t val = signxor;
661 switch(endbytecase){
662 case 2:case 5:
663 /* 24 */
664 *o++=val;
665 // fall through
666 case 1:case 4:
667 /* LE 16 */
668 *o++=val>>8;
669 // fall through
670 case 0:case 3:
671 /* 8 */
672 *o++=val>>16;
673 break;
676 o+=bytestep;
680 return bytes*ch*link->samples;
683 extern pthread_mutex_t input_mutex;
684 extern mix_settings *mix_set;
686 /* playback must be halted for new output settings to take hold */
687 void *playback_thread(void *dummy){
688 int i,j,k;
689 unsigned char *audiobuf;
690 int bigendianp=(AFMT_S16_NE==AFMT_S16_BE?1:0);
691 time_linkage *link;
692 int result;
693 off_t output_bytecount=0;
695 int att_last=master_att;
697 /* for output feedback */
698 float *rms=alloca(sizeof(*rms)*OUTPUT_CHANNELS);
699 float *peak=alloca(sizeof(*peak)*OUTPUT_CHANNELS);
701 long offset=0;
703 /* monitor setup */
704 FILE *monitor_fd=NULL;
705 int monitor_bits;
706 int monitor_ch;
707 int monitor_endian=bigendianp;
708 int monitor_signp=1;
709 int monitor_started=0;
710 int monitor_devicenum=outset.monitor.device;
712 int stdout_bits;
713 int stdout_ch;
714 int stdout_endian;
715 int stdout_signp=1;
716 int stdout_started=0;
717 int stdout_format=outset.stdout.format;
719 /* inspect mixdown; how many channels are in use? */
721 for(j=OUTPUT_CHANNELS-1;j>=0;j--){
722 for(i=0;i<input_ch;i++){
723 mix_settings *m=mix_set+i;
725 if(m->placer_destA[j] ||
726 m->placer_destB[j])break;
728 for(k=0;k<MIX_BLOCKS;k++)
729 if(m->insert_dest[k][j])break;
730 if(k<MIX_BLOCKS)break;
732 if(i<input_ch)break;
734 monitor_ch=stdout_ch=j+1;
737 if(output_monitor_available){
738 int ch=outset.monitor.ch;
739 int bits=outset.monitor.bytes;
741 /* channels */
742 switch(ch){
743 case 0:
744 break;
745 case 1:case 2:
746 monitor_ch=ch;
747 break;
748 default:
749 monitor_ch=(ch-1)*2;
750 break;
753 /* bits */
754 switch(bits){
755 case 0:case 2:
756 /* 'auto', 16 */
757 monitor_bits=16;
758 break;
759 case 1:
760 monitor_bits=8;
761 break;
762 case 3:
763 monitor_bits=24;
764 break;
768 if(output_stdout_available){
769 int ch=outset.stdout.ch;
770 int bits=outset.stdout.bytes;
772 /* channels */
773 switch(ch){
774 case 0:
775 break;
776 case 1:case 2:
777 stdout_ch=ch;
778 break;
779 default:
780 stdout_ch=(ch-1)*2;
781 break;
784 /* bits */
785 switch(bits){
786 case 0:
787 if(output_stdout_device)
788 stdout_bits=16;
789 else
790 stdout_bits=24;
791 break;
792 case 1:
793 stdout_bits=8;
794 break;
795 case 2:
796 stdout_bits=16;
797 break;
798 case 3:
799 stdout_bits=24;
800 break;
805 audiobuf=malloc(input_size*OUTPUT_CHANNELS*4); // largest possible need
807 while(1){
809 /* the larger lock against seeking is primarily cosmetic, but
810 keeps the metadata strictly in sync. This lock is only against
811 seeks. */
812 pthread_mutex_lock(&input_mutex);
814 if(playback_seeking){
815 pipeline_reset();
816 playback_seeking=0;
819 if(playback_exit){
820 pthread_mutex_unlock(&input_mutex);
821 break;
824 offset+=input_size;
826 /* get data */
827 link=input_read();
828 result=link->samples;
829 pthread_mutex_unlock(&input_mutex);
831 /* channel pipeline */
832 link=mute_read(link);
833 result|=link->samples;
834 link=declip_read(link);
835 result|=link->samples;
836 link=deverb_read_channel(link);
837 result|=link->samples;
838 link=multicompand_read_channel(link);
839 result|=link->samples;
840 link=singlecomp_read_channel(link);
841 result|=link->samples;
842 link=eq_read_channel(link);
843 result|=link->samples;
845 /* per-channel plate reverb generates more channels than it takes;
846 these are swallowed and mixed immediately by mixdown */
848 time_linkage *reverbA;
849 time_linkage *reverbB;
850 link=p_reverb_read_channel(link,&reverbA,&reverbB);
852 link=mix_read(link,reverbA,reverbB);
853 result|=link->samples;
856 /* master pipeline */
857 link=multicompand_read_master(link);
858 result|=link->samples;
859 link=singlecomp_read_master(link);
860 result|=link->samples;
861 link=eq_read_master(link);
862 result|=link->samples;
863 link=p_reverb_read_master(link);
864 result|=link->samples;
866 if(!result)break;
867 /************/
869 /* master att */
870 if(link->samples>0){
871 int att=master_att;
873 if(att==att_last){
874 float scale=fromdB(att/10.);
876 for(i=0;i<link->samples;i++)
877 for(j=0;j<link->channels;j++)
878 link->data[j][i]*=scale;
879 }else{
880 /* slew-limit the scaling */
881 float scale=fromdB(att_last*.1);
882 float mult=fromdB((att-att_last)*.1 / input_size);
884 for(i=0;i<link->samples;i++){
885 for(j=0;j<link->channels;j++)
886 link->data[j][i]*=scale;
887 scale*=mult;
889 att_last=att;
893 link=limit_read(link);
895 /************/
897 if(link->samples>0){
899 /* final limiting and conversion */
901 /* monitor output */
902 if(output_monitor_available){
903 if(outset.panel_active[0]){
905 /* lazy playback init */
906 if(!monitor_started){
908 /* nonblocking open... just in case this is an exclusive
909 use device currently used by something else */
910 int mfd=open(monitor_list[monitor_devicenum].file,O_RDWR|O_NONBLOCK);
911 if(mfd==-1){
912 fprintf(stderr,"unable to open audio monitor device %s for playback.\n",
913 monitor_list[monitor_devicenum].file);
914 outpanel_monitor_off();
915 }else{
916 fcntl(mfd,F_SETFL,0); /* unset non-blocking */
917 monitor_fd=fdopen(dup(mfd),"wb");
918 close(mfd);
920 if(monitor_fd==NULL){
921 fprintf(stderr,"unable to fdopen audio monitor device %s for playback.\n",
922 monitor_list[monitor_devicenum].file);
923 outpanel_monitor_off();
924 }else{
925 if(setvbuf(monitor_fd, NULL, _IONBF , 0)){
926 fprintf(stderr,"Unable to remove block buffering on audio monitor; continuing\n");
929 if(output_startup(monitor_fd,monitor_list[monitor_devicenum].type,0,input_rate,
930 &monitor_ch,&monitor_endian,&monitor_bits,&monitor_signp)){
931 outpanel_monitor_off();
932 fclose(monitor_fd);
933 monitor_fd=NULL;
934 }else
935 monitor_started=1;
940 if(monitor_started){
941 int outbytes=outpack(link,audiobuf,monitor_ch,
942 monitor_bits,monitor_endian,monitor_signp,
943 outset.monitor.source);
945 fwrite(audiobuf,1,outbytes,monitor_fd);
947 }else{
948 if(monitor_started){
949 /* halt playback */
950 output_halt(monitor_fd,monitor_list[monitor_devicenum].type,0,input_rate,monitor_ch,
951 monitor_endian,monitor_bits,monitor_signp,-1);
952 fclose(monitor_fd);
953 monitor_fd=NULL;
954 monitor_started=0;
959 /* standard output */
960 if(output_stdout_available){
961 if(outset.panel_active[1]){
963 /* lazy playback/header init */
964 if(!stdout_started){
965 if(output_startup(stdout,output_stdout_device,stdout_format,input_rate,
966 &stdout_ch,&stdout_endian,&stdout_bits,&stdout_signp))
967 outpanel_stdout_off();
968 else
969 stdout_started=1;
972 if(stdout_started){
973 int outbytes=outpack(link,audiobuf,stdout_ch,
974 stdout_bits,stdout_endian,stdout_signp,
975 outset.stdout.source);
977 output_bytecount+=fwrite(audiobuf,1,outbytes,stdout);
979 }else{
980 if(stdout_started){
981 /* if stdout is a device, halt playback. Otherwise, write nothing */
982 if(output_stdout_device){
983 /* halt playback */
984 output_halt(stdout,output_stdout_device,0,input_rate,stdout_ch,stdout_endian,
985 stdout_bits,stdout_signp,-1);
986 stdout_started=0;
992 /* feedback */
993 memset(rms,0,sizeof(*rms)*OUTPUT_CHANNELS);
994 memset(peak,0,sizeof(*peak)*OUTPUT_CHANNELS);
996 for(j=0;j<OUTPUT_CHANNELS;j++){
997 if(!mute_channel_muted(link->active,j))
998 for(i=0;i<link->samples;i++){
999 float dval=link->data[j][i];
1000 dval*=dval;
1001 if(dval>peak[j])peak[j]=dval;
1002 rms[j]+= dval;
1006 for(j=0;j<OUTPUT_CHANNELS;j++)
1007 rms[j]/=link->samples;
1009 /* inform Lord Vader his shuttle is ready */
1010 push_output_feedback(peak,rms);
1012 write(eventpipe[1],"",1);
1016 /* shut down monitor */
1017 if(monitor_fd){
1018 if(monitor_started)
1019 output_halt(monitor_fd,monitor_list[monitor_devicenum].type,0,input_rate,monitor_ch,
1020 monitor_endian,monitor_bits,monitor_signp,-1);
1021 fclose(monitor_fd);
1024 /* shut down stdout playback or write final header */
1025 if(stdout_started)
1026 output_halt(stdout,output_stdout_device,stdout_format,input_rate,stdout_ch,stdout_endian,
1027 stdout_bits,stdout_signp,output_bytecount);
1029 pipeline_reset();
1030 playback_active=0;
1031 playback_exit=0;
1032 if(audiobuf)free(audiobuf);
1034 write(eventpipe[1],"",1);
1035 return(NULL);
1038 /* for access from UI */
1039 void output_halt_playback(void){
1040 if(playback_active){
1041 playback_exit=1;
1043 while(1){
1044 if(playback_active){
1045 sched_yield();
1046 }else
1047 break;