annotate libao2/pl_surround.c @ 4559:5dc383bb1c82

added mga_top_reserved module parameter to skip a configurable amount of space at the top of video memory. this is needed to prevent corruption of the kernel's console font when using the "fastfont" option with matroxfb.
author rfelker
date Thu, 07 Feb 2002 02:07:29 +0000
parents d358dc143a9e
children 8336b1cf8d70
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>
3317
614b4525d275 unistd.h required at least by FreeBSD
nexus
parents: 3313
diff changeset
41 #include <unistd.h>
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
42
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
43 #include "audio_out.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
44 #include "audio_plugin.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
45 #include "audio_plugin_internal.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
46 #include "afmt.h"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
47
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
48 #include "remez.h"
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
49 #include "firfilter.c"
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
50
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
51 static ao_info_t info =
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
52 {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
53 "Surround decoder plugin",
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
54 "surround",
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
55 "Steve Davies <steve@daviesfam.org>",
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
56 ""
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 LIBAO_PLUGIN_EXTERN(surround)
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
60
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
61 // local data
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
62 typedef struct pl_surround_s
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
63 {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
64 int passthrough; // Just be a "NO-OP"
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
65 int msecs; // Rear channel delay in milliseconds
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
66 int16_t* databuf; // Output audio buffer
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
67 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
68 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
69 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
70 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
71 double* filter_coefs_surround; // FIR filter coefficients for surround sound 7kHz lowpass
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
72 int rate; // input data rate
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
73 int format; // input format
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
74 int input_channels; // input channels
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
75
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
76 } pl_surround_t;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
77
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
78 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
79
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
80 // to set/get/query special features/parameters
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
81 static int control(int cmd,int arg){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
82 switch(cmd){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
83 case AOCONTROL_PLUGIN_SET_LEN:
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
84 if (pl_surround.passthrough) return CONTROL_OK;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
85 //fprintf(stderr, "pl_surround: AOCONTROL_PLUGIN_SET_LEN with arg=%d\n", arg);
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
86 //fprintf(stderr, "pl_surround: ao_plugin_data.len=%d\n", ao_plugin_data.len);
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
87 // Allocate an output buffer
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
88 if (pl_surround.databuf != NULL) {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
89 free(pl_surround.databuf); pl_surround.databuf = NULL;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
90 }
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
91 // Allocate output buffer
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
92 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
93 // Return back smaller len so we don't get overflowed...
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
94 ao_plugin_data.len /= 2;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
95 return CONTROL_OK;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
96 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
97 return -1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
98 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
99
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
100 // open & setup audio device
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
101 // return: 1=success 0=fail
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
102 static int init(){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
103
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
104 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
105 if (ao_plugin_data.channels != 2) {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
106 fprintf(stderr, "pl_surround: source audio must have 2 channels, using passthrough mode\n");
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
107 pl_surround.passthrough = 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
108 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
109 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
110 if (ao_plugin_data.format != AFMT_S16_LE) {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
111 fprintf(stderr, "pl_surround: I'm dumb and can only handle AFMT_S16_LE audio format, using passthrough mode\n");
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
112 pl_surround.passthrough = 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
113 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
114 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
115
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
116 pl_surround.passthrough = 0;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
117
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
118 /* Store info on input format to expect */
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
119 pl_surround.rate=ao_plugin_data.rate;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
120 pl_surround.format=ao_plugin_data.format;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
121 pl_surround.input_channels=ao_plugin_data.channels;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
122
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
123 // Input 2 channels, output will be 4 - tell ao_plugin
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
124 ao_plugin_data.channels = 4;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
125 ao_plugin_data.sz_mult /= 2;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
126
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
127 // 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
128 // 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
129 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
130 // Allocate delay buffers
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
131 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
132 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
133 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
134 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
135 pl_surround.delaybuf_pos = 0;
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
136 // Surround filer coefficients
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
137 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
138 //dump_filter_coefficients(pl_surround.filter_coefs_surround);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3485
diff changeset
139 //testfilter(pl_surround.filter_coefs_surround, 32, pl_surround.rate);
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
140 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
141 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
142
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
143 // close plugin
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
144 static void uninit(){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
145 // fprintf(stderr, "pl_surround: uninit called!\n");
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
146 if (pl_surround.passthrough) return;
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
147 if(pl_surround.Ls_delaybuf)
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
148 free(pl_surround.Ls_delaybuf);
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
149 if(pl_surround.Rs_delaybuf)
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
150 free(pl_surround.Rs_delaybuf);
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
151 if(pl_surround.databuf)
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
152 free(pl_surround.databuf);
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
153 pl_surround.delaybuf_len=0;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
154 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
155
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
156 // empty buffers
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
157 static void reset()
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
158 {
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
159 if (pl_surround.passthrough) return;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
160 //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
161 pl_surround.delaybuf_pos = 0;
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
162 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
163 memset(pl_surround.Rs_delaybuf, 0, sizeof(int16_t)*pl_surround.delaybuf_len);
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
164 }
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
165
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
166 // The beginnings of an active matrix...
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
167 static double steering_matrix[][12] = {
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
168 // 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
169 {.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
170 };
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
171
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
172 // Experimental moving average dominances
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
173 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
174
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
175 // processes 'ao_plugin_data.len' bytes of 'data'
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
176 // called for every block of data
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
177 static int play(){
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
178 int16_t *in, *out;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
179 int i, samples;
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
180 double *matrix = steering_matrix[0]; // later we'll index based on detected dominance
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
181
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
182 if (pl_surround.passthrough) return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
183
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
184 // 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
185
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
186 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
187 out = pl_surround.databuf; in = (int16_t *)ao_plugin_data.data;
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
188
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
189 // 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
190 //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
191 //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
192
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
193 for (i=0; i<samples; i++) {
3373
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
194
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
195 // Dominance:
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
196 //abs(in[0]) abs(in[1]);
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
197 //abs(in[0]+in[1]) abs(in[0]-in[1]);
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
198 //10 * log( abs(in[0]) / (abs(in[1])|1) );
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
199 //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
200
3410
3eb15016e454 still fiddling with surround levels
steve
parents: 3373
diff changeset
201 // About volume balancing...
3373
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
202 // Surround encoding does the following:
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
203 // 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
204 // 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
205 // (Lt-Rt)
3410
3eb15016e454 still fiddling with surround levels
steve
parents: 3373
diff changeset
206 // 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
207 // 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
208 // 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
209 // 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
210 // 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
211 // this keeps the overall balance, but guarantees no overflow.
3373
e5b881ac961e Corrected front:surround levels
steve
parents: 3317
diff changeset
212
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
213 // output front left and right
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
214 out[0] = matrix[0]*in[0] + matrix[1]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
215 out[1] = matrix[2]*in[0] + matrix[3]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
216 // 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
217 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
218 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
219 #ifdef SPLITREAR
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
220 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
221 pl_surround.delaybuf_len, 32, pl_surround.filter_coefs_surround);
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
222 #else
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
223 out[3] = -out[2];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
224 #endif
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
225 // calculate and save surround for 20msecs time
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
226 #ifdef SPLITREAR
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
227 pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos] =
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
228 matrix[6]*in[0] + matrix[7]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
229 pl_surround.Rs_delaybuf[pl_surround.delaybuf_pos++] =
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
230 matrix[8]*in[0] + matrix[9]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
231 #else
3718
d358dc143a9e error for non-stereo surrounds
steve
parents: 3681
diff changeset
232 pl_surround.Ls_delaybuf[pl_surround.delaybuf_pos++] =
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
233 matrix[4]*in[0] + matrix[5]*in[1];
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
234 #endif
3485
439b0b1d50b9 include 7kHz lowpass filter for surround channels, as per Dolby recommendation
steve
parents: 3420
diff changeset
235 pl_surround.delaybuf_pos %= pl_surround.delaybuf_len;
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
236
3313
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
237 // next samples...
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
238 in = &in[pl_surround.input_channels]; out = &out[4];
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
239 }
3681
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
240
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
241 // Show some state
26126e5c3532 surround channels can now be decoded in stereoish
steve
parents: 3495
diff changeset
242 //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
243
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
244 // Set output block/len
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
245 ao_plugin_data.data=pl_surround.databuf;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
246 ao_plugin_data.len=samples*sizeof(int16_t)*4;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
247 return 1;
76a3421bc421 Dolby Surround decoding audio plugin
steve
parents:
diff changeset
248 }