annotate libao2/pl_surround.c @ 8763:19e96e60a3d0

Speed optimizations (runs twise as fast) and bugfix (wrong cutoff frequency buffer over run noise and garbeled output when wrong input format)
author anders
date Sat, 04 Jan 2003 06:19:25 +0000
parents 46d21c0f36aa
children 12b1790038b0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
1 /*
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
2 This is an ao2 plugin to do simple decoding of matrixed surround
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
3 sound. This will provide a (basic) surround-sound effect from
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
4 audio encoded for Dolby Surround, Pro Logic etc.
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
5
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
6 * This program is free software; you can redistribute it and/or modify
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
7 * it under the terms of the GNU General Public License as published by
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
8 * the Free Software Foundation; either version 2 of the License, or
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
9 * (at your option) any later version.
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
10 *
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
11 * This program is distributed in the hope that it will be useful,
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
14 * GNU General Public License for more details.
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
15 *
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
16 * You should have received a copy of the GNU General Public License
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
17 * along with this program; if not, write to the Free Software
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
19
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
20 Original author: Steve Davies <steve@daviesfam.org>
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
21 */
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
22
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
23 /* The principle: Make rear channels by extracting anti-phase data
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
24 from the front channels, delay by 20msec and feed to rear in anti-phase
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
25 */
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
26
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
27
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
28 // SPLITREAR: Define to decode two distinct rear channels -
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
29 // this doesn't work so well in practice because
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
30 // separation in a passive matrix is not high.
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
31 // C (dialogue) to Ls and Rs 14dB or so -
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
32 // so dialogue leaks to the rear.
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
33 // Still - give it a try and send feedback.
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
34 // comment this define for old behaviour of a single
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
35 // surround sent to rear in anti-phase
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
36 #define SPLITREAR
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
37
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
38
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
39 #include <stdio.h>
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
40 #include <stdlib.h>
6237
2eec40929570 warning fixes (string.h is required for memset)
pl
parents: 5501
diff changeset
41 #include <string.h>
3317
614b4525d275 unistd.h required at least by FreeBSD
nexus
parents: 3313
diff changeset
42 #include <unistd.h>
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
43
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
44 #include "audio_out.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
45 #include "audio_plugin.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
46 #include "audio_plugin_internal.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
47 #include "afmt.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
48
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
49 #include "remez.h"
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
50 #include "firfilter.c"
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
51
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
52 static ao_info_t info =
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
53 {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
54 "Surround decoder plugin",
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
55 "surround",
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
56 "Steve Davies <steve@daviesfam.org>",
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
57 ""
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
58 };
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
59
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
60 LIBAO_PLUGIN_EXTERN(surround)
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
61
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
62 // local data
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
63 typedef struct pl_surround_s
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
64 {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
65 int passthrough; // Just be a "NO-OP"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
66 int msecs; // Rear channel delay in milliseconds
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
67 int16_t* databuf; // Output audio buffer
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
68 int16_t* Ls_delaybuf; // circular buffer to be used for delaying Ls audio
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
69 int16_t* Rs_delaybuf; // circular buffer to be used for delaying Rs audio
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
70 int delaybuf_len; // delaybuf buffer length in samples
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
71 int delaybuf_pos; // offset in buffer where we are reading/writing
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
72 double* filter_coefs_surround; // FIR filter coefficients for surround sound 7kHz lowpass
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
73 int rate; // input data rate
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
74 int format; // input format
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
75 int input_channels; // input channels
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
76
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
77 } pl_surround_t;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
78
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
79 static pl_surround_t pl_surround={0,20,NULL,NULL,NULL,0,0,NULL,0,0,0};
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
80
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
81 // to set/get/query special features/parameters
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
82 static int control(int cmd,int arg){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
83 switch(cmd){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
84 case AOCONTROL_PLUGIN_SET_LEN:
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
85 if (pl_surround.passthrough) return CONTROL_OK;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
86 //fprintf(stderr, "pl_surround: AOCONTROL_PLUGIN_SET_LEN with arg=%d\n", arg);
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
87 //fprintf(stderr, "pl_surround: ao_plugin_data.len=%d\n", ao_plugin_data.len);
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
88 // Allocate an output buffer
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
89 if (pl_surround.databuf != NULL) {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
90 free(pl_surround.databuf); pl_surround.databuf = NULL;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
91 }
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
92 // Allocate output buffer
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
93 pl_surround.databuf = calloc(ao_plugin_data.len, 1);
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
94 // Return back smaller len so we don't get overflowed...
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
95 ao_plugin_data.len /= 2;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
96 return CONTROL_OK;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
97 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
98 return -1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
99 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
100
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
101 // open & setup audio device
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
102 // return: 1=success 0=fail
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
103 static int init(){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
104
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
105 fprintf(stderr, "pl_surround: init input rate=%d, channels=%d\n", ao_plugin_data.rate, ao_plugin_data.channels);
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
106 if (ao_plugin_data.channels != 2) {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
107 fprintf(stderr, "pl_surround: source audio must have 2 channels, using passthrough mode\n");
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
108 pl_surround.passthrough = 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
109 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
110 }
8741
46d21c0f36aa (nicer) endianness fix for every plugin except pl_format
colin
parents: 8123
diff changeset
111 if (ao_plugin_data.format != AFMT_S16_NE) {
46d21c0f36aa (nicer) endianness fix for every plugin except pl_format
colin
parents: 8123
diff changeset
112 fprintf(stderr, "pl_surround: I'm dumb and can only handle AFMT_S16_NE audio format, using passthrough mode\n");
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
113 pl_surround.passthrough = 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
114 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
115 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
116
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
117 pl_surround.passthrough = 0;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
118
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
119 /* Store info on input format to expect */
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
120 pl_surround.rate=ao_plugin_data.rate;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
121 pl_surround.format=ao_plugin_data.format;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
122 pl_surround.input_channels=ao_plugin_data.channels;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
123
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
124 // Input 2 channels, output will be 4 - tell ao_plugin
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
125 ao_plugin_data.channels = 4;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
126 ao_plugin_data.sz_mult /= 2;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
127
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
128 // Figure out buffer space (in int16_ts) needed for the 15msec delay
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
129 // Extra 31 samples allow for lowpass filter delay (taps-1)
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
130 pl_surround.delaybuf_len = (pl_surround.rate * pl_surround.msecs / 1000) + 31;
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
131 // Allocate delay buffers
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
132 pl_surround.Ls_delaybuf=(void*)calloc(pl_surround.delaybuf_len,sizeof(int16_t));
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
133 pl_surround.Rs_delaybuf=(void*)calloc(pl_surround.delaybuf_len,sizeof(int16_t));
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
134 fprintf(stderr, "pl_surround: %dmsec surround delay, rate %d - buffers are %d bytes each\n",
3420
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
135 pl_surround.msecs,pl_surround.rate, pl_surround.delaybuf_len*sizeof(int16_t));
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
136 pl_surround.delaybuf_pos = 0;
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
137 // Surround filer coefficients
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
138 pl_surround.filter_coefs_surround = calc_coefficients_7kHz_lowpass(pl_surround.rate);
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
139 //dump_filter_coefficients(pl_surround.filter_coefs_surround);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
140 //testfilter(pl_surround.filter_coefs_surround, 32, pl_surround.rate);
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
141 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
142 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
143
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
144 // close plugin
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
145 static void uninit(){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
146 // fprintf(stderr, "pl_surround: uninit called!\n");
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
147 if (pl_surround.passthrough) return;
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
148 if(pl_surround.Ls_delaybuf)
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
149 free(pl_surround.Ls_delaybuf);
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
150 if(pl_surround.Rs_delaybuf)
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
151 free(pl_surround.Rs_delaybuf);
5501
8336b1cf8d70 Free fix by kisg@lme.linux.hu
atmos4
parents: 3718
diff changeset
152 if(pl_surround.databuf) {
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
153 free(pl_surround.databuf);
5501
8336b1cf8d70 Free fix by kisg@lme.linux.hu
atmos4
parents: 3718
diff changeset
154 pl_surround.databuf = NULL;
8336b1cf8d70 Free fix by kisg@lme.linux.hu
atmos4
parents: 3718
diff changeset
155 }
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
156 pl_surround.delaybuf_len=0;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
157 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
158
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
159 // empty buffers
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
160 static void reset()
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
161 {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
162 if (pl_surround.passthrough) return;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
163 //fprintf(stderr, "pl_surround: reset called\n");
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
164 pl_surround.delaybuf_pos = 0;
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
165 memset(pl_surround.Ls_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len);
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
166 memset(pl_surround.Rs_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len);
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
167 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
168
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
169 // The beginnings of an active matrix...
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
170 static double steering_matrix[][12] = {
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
171 // LL RL LR RR LS RS LLs RLs LRs RRs LC RC
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
172 {.707, .0, .0, .707, .5, -.5, .5878, -.3928, .3928, -.5878, .5, .5},
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
173 };
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
174
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
175 // Experimental moving average dominances
8123
9fc45fe0d444 *HUGE* set of compiler warning fixes, unused variables removal
arpi
parents: 6237
diff changeset
176 //static int amp_L = 0, amp_R = 0, amp_C = 0, amp_S = 0;
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
177
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
178 // processes 'ao_plugin_data.len' bytes of 'data'
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
179 // called for every block of data
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
180 static int play(){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
181 int16_t *in, *out;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
182 int i, samples;
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
183 double *matrix = steering_matrix[0]; // later we'll index based on detected dominance
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
184
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
185 if (pl_surround.passthrough) return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
186
3420
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
187 // fprintf(stderr, "pl_surround: play %d bytes, %d samples\n", ao_plugin_data.len, samples);
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
188
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
189 samples = ao_plugin_data.len / sizeof(int16_t) / pl_surround.input_channels;
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
190 out = pl_surround.databuf; in = (int16_t *)ao_plugin_data.data;
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
191
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
192 // Testing - place a 1kHz tone on Lt and Rt in anti-phase: should decode in S
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
193 //sinewave(in, samples, pl_surround.input_channels, 1000, 0.0, pl_surround.rate);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
194 //sinewave(&in[1], samples, pl_surround.input_channels, 1000, PI, pl_surround.rate);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
195
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
196 for (i=0; i<samples; i++) {
3373
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
197
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
198 // Dominance:
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
199 //abs(in[0]) abs(in[1]);
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
200 //abs(in[0]+in[1]) abs(in[0]-in[1]);
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
201 //10 * log( abs(in[0]) / (abs(in[1])|1) );
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
202 //10 * log( abs(in[0]+in[1]) / (abs(in[0]-in[1])|1) );
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
203
3410
3eb15016e454 still fiddling with surround levels
steve
parents: 3373
diff changeset
204 // About volume balancing...
3373
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
205 // Surround encoding does the following:
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
206 // Lt=L+.707*C+.707*S, Rt=R+.707*C-.707*S
3420
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
207 // So S should be extracted as:
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
208 // (Lt-Rt)
3410
3eb15016e454 still fiddling with surround levels
steve
parents: 3373
diff changeset
209 // But we are splitting the S to two output channels, so we
3420
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
210 // must take 3dB off as we split it:
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
211 // Ls=Rs=.707*(Lt-Rt)
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
212 // Trouble is, Lt could be +32767, Rt -32768, so possibility that S will
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
213 // overflow. So to avoid that, we cut L/R by 3dB (*.707), and S by 6dB (/2).
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
214 // this keeps the overall balance, but guarantees no overflow.
3373
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
215
3420
cfc10bc948c4 split surround delay buf into Ls and Rs in prep for active decoding stuff, and fiddled a bit more with surround level
steve
parents: 3410
diff changeset
216 // output front left and right
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
217 out[0] = matrix[0]*in[0] + matrix[1]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
218 out[1] = matrix[2]*in[0] + matrix[3]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
219 // output Ls and Rs - from 20msec ago, lowpass filtered @ 7kHz
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
220 out[2] = firfilter(pl_surround.Ls_delaybuf, pl_surround.delaybuf_pos,
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
221 pl_surround.delaybuf_len, 32, pl_surround.filter_coefs_surround);
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
222 #ifdef SPLITREAR
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
223 out[3] = firfilter(pl_surround.Rs_delaybuf, pl_surround.delaybuf_pos,
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
224 pl_surround.delaybuf_len, 32, pl_surround.filter_coefs_surround);
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
225 #else
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
226 out[3] = -out[2];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
227 #endif
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
228 // calculate and save surround for 20msecs time
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
229 #ifdef SPLITREAR
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
230 pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos] =
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
231 matrix[6]*in[0] + matrix[7]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
232 pl_surround.Rs_delaybuf[pl_surround.delaybuf_pos++] =
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
233 matrix[8]*in[0] + matrix[9]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
234 #else
3718
d358dc143a9e error for non-stereo surrounds
steve
parents: 3681
diff changeset
235 pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos++] =
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
236 matrix[4]*in[0] + matrix[5]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
237 #endif
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
238 pl_surround.delaybuf_pos %= pl_surround.delaybuf_len;
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
239
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
240 // next samples...
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
241 in = &in[pl_surround.input_channels]; out = &out[4];
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
242 }
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
243
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
244 // Show some state
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
245 //printf("\npl_surround: delaybuf_pos=%d, samples=%d\r\033[A", pl_surround.delaybuf_pos, samples);
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
246
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
247 // Set output block/len
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
248 ao_plugin_data.data=pl_surround.databuf;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
249 ao_plugin_data.len=samples*sizeof(int16_t)*4;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
250 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
251 }