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)
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>
33 #include "multicompand.h"
34 #include "singlecomp.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
));
56 void pipeline_reset(){
57 int flags
=fcntl(eventpipe
[0],F_GETFL
);
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 */
77 typedef struct output_feedback
{
78 feedback_generic parent_class
;
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
);
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
);
110 int output_feedback_deep(void){
111 return feedback_deep(&feedpool
);
114 static void PutNumLE(long num
,FILE *f
,int bytes
){
117 fputc((num
>>(i
<<3))&0xff,f
);
122 static void PutNumBE(long num
,FILE *f
,int bytes
){
125 fputc((num
>>24)&0xff,f
);
127 fputc((num
>>16)&0xff,f
);
129 fputc((num
>>8)&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
){
140 double fMant
, fsMant
;
141 u_int32_t hiMant
, loMant
;
151 expon
= 0; hiMant
= 0; loMant
= 0;
154 fMant
= frexp(num
, &expon
);
155 if ((expon
> 16384) || !(fMant
< 1)) { /* Infinity or NaN */
156 expon
= sign
|0x7FFF; hiMant
= 0; loMant
= 0; /* infinity */
160 if (expon
< 0) { /* denormalized */
161 fMant
= ldexp(fMant
, expon
);
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;
176 bytes
[2] = hiMant
>> 24;
177 bytes
[3] = hiMant
>> 16;
178 bytes
[4] = hiMant
>> 8;
180 bytes
[6] = loMant
>> 24;
181 bytes
[7] = loMant
>> 16;
182 bytes
[8] = loMant
>> 8;
186 static void WriteWav(FILE *f
,long channels
,long rate
,long bits
,long duration
){
188 if(fseek(f
,0,SEEK_SET
))
191 PutNumLE(duration
+44-8,f
,4);
192 fprintf(f
,"WAVEfmt ");
195 PutNumLE(channels
,f
,2);
197 PutNumLE(rate
*channels
*((bits
-1)/8+1),f
,4);
198 PutNumLE(((bits
-1)/8+1)*channels
,f
,2);
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
;
211 if(fseek(f
,0,SEEK_SET
))
214 /* Again, quick and dirty */
218 PutNumBE(size
-8,f
,4);
224 PutNumBE(2726318400UL,f
,4);
228 PutNumBE(channels
,f
,2);
230 PutNumBE(frames
,f
,4);
235 ConvertToIeeeExtended(rate
,ieee
);
240 fprintf(f
,"not compressed");
245 PutNumBE(duration
+8,f
,4);
254 static int isachr(int f
){
258 if(S_ISCHR(s
.st_mode
)) return 1;
262 static int isareg(int f
){
266 if(S_ISREG(s
.st_mode
)) return 1;
270 static int ilog(long x
){
280 static int is_oss(int f
){
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;
295 static int is_alsa(int f
){
300 int type
=(int)(s
.st_rdev
>>8);
302 // is this a Linux ALSA audio device (Major 116) ?
303 if(type
==116)return 1;
309 static int isaudio(int outfileno
){
310 if(is_oss(outfileno
))return 1;
311 if(is_alsa(outfileno
))return 2;
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
){
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
;
339 "\nStdout is pointing to an ALSA sound device;\n"
340 "Postfish does not yet support ALSA playback.\n\n");
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;
354 #include <sys/types.h>
355 #include <sys/stat.h>
357 output_monitor_entry
*monitor_list
;
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
){
367 monitor_list
=realloc(monitor_list
,
368 monitor_entries
*sizeof(*monitor_list
));
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");
386 fprintf(stderr
,"Odd; could not open /dev to look for audio devices.\n");
390 while((de
=readdir(d
))){
393 snprintf(buf
,PATH_MAX
,"/dev/%s",de
->d_name
);
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
);
403 add_monitor(buf
,de
->d_name
,1);
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;
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
);
438 # define AFMT_S24_LE 0x00000800
439 # define AFMT_S24_BE 0x00001000
440 # define AFMT_U24_LE 0x00002000
441 # define AFMT_U24_BE 0x00004000
444 static int OSS_playback_startup(FILE *f
, int rate
, int *ch
, int *endian
, int *bits
,int *signp
){
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
455 while(local_ch
|| local_bits
>16){
469 if(*endian
)format
=AFMT_S24_BE
;
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
;
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 */
491 int ret
=ioctl(fd
,SNDCTL_DSP_SETFMT
,&temp
);
492 if(ret
|| format
!=temp
) goto failset
;
497 int ret
=ioctl(fd
,SNDCTL_DSP_CHANNELS
,&temp
);
498 if(ret
|| temp
!=local_ch
) goto failset
;
503 int ret
=ioctl(fd
,SNDCTL_DSP_SPEED
,&temp
);
504 if(ret
|| temp
!=rate
) goto failset
;
513 /* first try decreasing bit depth */
518 /* next, drop channels */
523 ioctl(fd
,SNDCTL_DSP_RESET
);
526 if(failflag
|| downgrade
)
527 fprintf(stderr
,"Unable to set playback for %d bits, %d channels, %dHz\n",
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;
540 static int output_startup(FILE *f
, int devtype
, int format
, int rate
, int *ch
, int *endian
, int *bits
,int *signp
){
542 case 0: // pipe, regular file or file device
546 ftruncate(fileno(f
),0);
547 WriteWav(f
,*ch
,rate
,*bits
,-1);
550 if(*bits
==8)*signp
=0;
554 ftruncate(fileno(f
),0);
555 WriteAifc(f
,*ch
,rate
,*bits
,-1);
560 /* raw little endian */
563 if(*bits
==8)*signp
=0;
569 if(*bits
==8)*signp
=0;
572 fprintf(stderr
,"Unsupported output file format selected!\n");
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");
586 static void output_halt(FILE *f
,int devtype
,int format
, int rate
, int ch
, int endian
, int bits
,int signp
,
592 WriteWav(f
,ch
,rate
,bits
,bytecount
); // will complete header only if stream is seekable
595 WriteAifc(f
,ch
,rate
,bits
,bytecount
); // will complete header only if stream is seekable
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);
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
++){
624 int32_t val
=rint(dval
*8388608.);
625 if(val
>8388607)val
=8388607;
626 if(val
<-8388608)val
=-8388608;
658 for(i
=0;i
<link
->samples
;i
++){
659 int32_t val
= signxor
;
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
){
689 unsigned char *audiobuf
;
690 int bigendianp
=(AFMT_S16_NE
==AFMT_S16_BE
?1:0);
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
);
704 FILE *monitor_fd
=NULL
;
707 int monitor_endian
=bigendianp
;
709 int monitor_started
=0;
710 int monitor_devicenum
=outset
.monitor
.device
;
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;
734 monitor_ch
=stdout_ch
=j
+1;
737 if(output_monitor_available
){
738 int ch
=outset
.monitor
.ch
;
739 int bits
=outset
.monitor
.bytes
;
768 if(output_stdout_available
){
769 int ch
=outset
.stdout
.ch
;
770 int bits
=outset
.stdout
.bytes
;
787 if(output_stdout_device
)
805 audiobuf
=malloc(input_size
*OUTPUT_CHANNELS
*4); // largest possible need
809 /* the larger lock against seeking is primarily cosmetic, but
810 keeps the metadata strictly in sync. This lock is only against
812 pthread_mutex_lock(&input_mutex
);
814 if(playback_seeking
){
820 pthread_mutex_unlock(&input_mutex
);
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
;
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
;
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
;
893 link
=limit_read(link
);
899 /* final limiting and conversion */
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
);
912 fprintf(stderr
,"unable to open audio monitor device %s for playback.\n",
913 monitor_list
[monitor_devicenum
].file
);
914 outpanel_monitor_off();
916 fcntl(mfd
,F_SETFL
,0); /* unset non-blocking */
917 monitor_fd
=fdopen(dup(mfd
),"wb");
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();
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();
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
);
950 output_halt(monitor_fd
,monitor_list
[monitor_devicenum
].type
,0,input_rate
,monitor_ch
,
951 monitor_endian
,monitor_bits
,monitor_signp
,-1);
959 /* standard output */
960 if(output_stdout_available
){
961 if(outset
.panel_active
[1]){
963 /* lazy playback/header init */
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();
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
);
981 /* if stdout is a device, halt playback. Otherwise, write nothing */
982 if(output_stdout_device
){
984 output_halt(stdout
,output_stdout_device
,0,input_rate
,stdout_ch
,stdout_endian
,
985 stdout_bits
,stdout_signp
,-1);
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
];
1001 if(dval
>peak
[j
])peak
[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 */
1019 output_halt(monitor_fd
,monitor_list
[monitor_devicenum
].type
,0,input_rate
,monitor_ch
,
1020 monitor_endian
,monitor_bits
,monitor_signp
,-1);
1024 /* shut down stdout playback or write final header */
1026 output_halt(stdout
,output_stdout_device
,stdout_format
,input_rate
,stdout_ch
,stdout_endian
,
1027 stdout_bits
,stdout_signp
,output_bytecount
);
1032 if(audiobuf
)free(audiobuf
);
1034 write(eventpipe
[1],"",1);
1038 /* for access from UI */
1039 void output_halt_playback(void){
1040 if(playback_active
){
1044 if(playback_active
){