1
/***************************************************************************
3
***************************************************************************/
6
/***************************************************************************
8
* This program is free software; you can redistribute it and/or modify *
9
* it under the terms of the GNU General Public License as published by *
10
* the Free Software Foundation; either version 2 of the License, or *
11
* (at your option) any later version. *
13
***************************************************************************/
20
#include <ADM_assert.h>
21
#include "ADM_library/default.h"
24
#include "audioeng_process.h"
25
#include "audiofilter_mixer.h"
26
#include "audiofilter_channel_route.h"
27
#include "audiofilter_dolby.h"
30
AUDMAudioFilterMixer::AUDMAudioFilterMixer(AUDMAudioFilter *instream,CHANNEL_CONF out):AUDMAudioFilter (instream)
33
_previous->rewind(); // rewind
34
ADM_assert(_output<CHANNEL_LAST);
37
double d; // Update duration
38
d=_wavHeader.byterate;
39
d/=_wavHeader.channels;
43
_wavHeader.channels = 1;
44
ch_route.output_type[0] = CH_MONO;
47
_wavHeader.channels = 2;
48
ch_route.output_type[0] = CH_FRONT_LEFT;
49
ch_route.output_type[1] = CH_FRONT_RIGHT;
52
_wavHeader.channels = 3;
53
ch_route.output_type[0] = CH_FRONT_LEFT;
54
ch_route.output_type[1] = CH_FRONT_RIGHT;
55
ch_route.output_type[2] = CH_REAR_CENTER;
58
_wavHeader.channels = 3;
59
ch_route.output_type[0] = CH_FRONT_LEFT;
60
ch_route.output_type[1] = CH_FRONT_RIGHT;
61
ch_route.output_type[2] = CH_FRONT_CENTER;
64
_wavHeader.channels = 4;
65
ch_route.output_type[0] = CH_FRONT_LEFT;
66
ch_route.output_type[1] = CH_FRONT_RIGHT;
67
ch_route.output_type[2] = CH_REAR_CENTER;
68
ch_route.output_type[3] = CH_FRONT_CENTER;
71
_wavHeader.channels = 4;
72
ch_route.output_type[0] = CH_FRONT_LEFT;
73
ch_route.output_type[1] = CH_FRONT_RIGHT;
74
ch_route.output_type[2] = CH_REAR_LEFT;
75
ch_route.output_type[3] = CH_REAR_RIGHT;
78
_wavHeader.channels = 5;
79
ch_route.output_type[0] = CH_FRONT_LEFT;
80
ch_route.output_type[1] = CH_FRONT_RIGHT;
81
ch_route.output_type[2] = CH_REAR_LEFT;
82
ch_route.output_type[3] = CH_REAR_RIGHT;
83
ch_route.output_type[4] = CH_FRONT_CENTER;
85
case CHANNEL_3F_2R_LFE:
86
_wavHeader.channels = 6;
87
ch_route.output_type[0] = CH_FRONT_LEFT;
88
ch_route.output_type[1] = CH_FRONT_RIGHT;
89
ch_route.output_type[2] = CH_REAR_LEFT;
90
ch_route.output_type[3] = CH_REAR_RIGHT;
91
ch_route.output_type[4] = CH_FRONT_CENTER;
92
ch_route.output_type[5] = CH_LFE;
94
case CHANNEL_DOLBY_PROLOGIC:
95
case CHANNEL_DOLBY_PROLOGIC2:
96
_wavHeader.channels = 2;
97
ch_route.output_type[0] = CH_FRONT_LEFT;
98
ch_route.output_type[1] = CH_FRONT_RIGHT;
103
d*=_wavHeader.channels;
104
_wavHeader.byterate = (uint32_t)ceil(d);
107
// printf("[mixer]Input channels : %u : %u \n",_previous->getInfo()->channels,input_channels);
108
// printf("[mixer]Out channels : %u : %u \n",_wavHeader.channels,ADM_channel_mixer[_output]);
112
AUDMAudioFilterMixer::~AUDMAudioFilterMixer()
116
static int MCOPY(float *in,float *out,uint32_t nbSample,uint32_t chan)
118
memcpy(out,in,nbSample*chan*sizeof(float));
119
return nbSample*chan;
123
static int MNto1(float *in,float *out,uint32_t nbSample,uint32_t chan)
126
int den=(chan+1)&0xfe;
127
for(int i=0;i<nbSample;i++)
130
for(int j=0;j<chan;j++)
132
out[0]=sum/(float)den;
140
static int MStereo(float *in,float *out,uint32_t nbSample,uint32_t chan)
142
memset(out, 0, sizeof(float) * nbSample * 2);
144
for (int i = 0; i < nbSample; i++) {
145
for (int c = 0; c < chan; c++) {
146
switch (ch_route.input_type[c]) {
148
case CH_FRONT_CENTER:
151
out[0] += *in * 0.707;
152
out[1] += *in * 0.707;
173
static int M2F1R(float *in,float *out,uint32_t nbSample,uint32_t chan)
175
memset(out, 0, sizeof(float) * nbSample * 3);
177
for (int i = 0; i < nbSample; i++) {
178
for (int c = 0; c < chan; c++) {
179
switch (ch_route.input_type[c]) {
181
case CH_FRONT_CENTER:
182
out[0] += *in * 0.707;
183
out[1] += *in * 0.707;
197
out[0] += *in * 0.595;
198
out[1] += *in * 0.595;
199
out[2] += *in * 0.595;
202
out[0] += *in * 0.707;
203
out[2] += *in * 0.707;
206
out[1] += *in * 0.707;
207
out[2] += *in * 0.707;
218
static int M3F(float *in,float *out,uint32_t nbSample,uint32_t chan)
220
memset(out, 0, sizeof(float) * nbSample * 3);
222
for (int i = 0; i < nbSample; i++) {
223
for (int c = 0; c < chan; c++) {
224
switch (ch_route.input_type[c]) {
226
case CH_FRONT_CENTER:
241
out[0] += *in * 0.595;
242
out[1] += *in * 0.595;
243
out[2] += *in * 0.595;
254
static int M3F1R(float *in,float *out,uint32_t nbSample,uint32_t chan)
256
memset(out, 0, sizeof(float) * nbSample * 4);
258
for (int i = 0; i < nbSample; i++) {
259
for (int c = 0; c < chan; c++) {
260
switch (ch_route.input_type[c]) {
262
case CH_FRONT_CENTER:
283
out[0] += *in * 0.707;
284
out[2] += *in * 0.707;
287
out[1] += *in * 0.707;
288
out[2] += *in * 0.707;
299
static int M2F2R(float *in,float *out,uint32_t nbSample,uint32_t chan)
301
memset(out, 0, sizeof(float) * nbSample * 4);
303
for (int i = 0; i < nbSample; i++) {
304
for (int c = 0; c < chan; c++) {
305
switch (ch_route.input_type[c]) {
307
case CH_FRONT_CENTER:
308
out[0] += *in * 0.707;
309
out[1] += *in * 0.707;
324
out[2] += *in * 0.707;
325
out[3] += *in * 0.707;
334
out[0] += *in * 0.707;
335
out[2] += *in * 0.707;
338
out[1] += *in * 0.707;
339
out[3] += *in * 0.707;
350
static int M3F2R(float *in,float *out,uint32_t nbSample,uint32_t chan)
352
memset(out, 0, sizeof(float) * nbSample * 5);
354
for (int i = 0; i < nbSample; i++) {
355
for (int c = 0; c < chan; c++) {
356
switch (ch_route.input_type[c]) {
358
case CH_FRONT_CENTER:
374
out[2] += *in * 0.707;
375
out[3] += *in * 0.707;
378
out[0] += *in * 0.459;
379
out[1] += *in * 0.459;
380
out[2] += *in * 0.459;
381
out[3] += *in * 0.459;
382
out[4] += *in * 0.459;
385
out[0] += *in * 0.707;
386
out[2] += *in * 0.707;
389
out[1] += *in * 0.707;
390
out[3] += *in * 0.707;
401
static int M3F2RLFE(float *in,float *out,uint32_t nbSample,uint32_t chan)
403
memset(out, 0, sizeof(float) * nbSample * 6);
405
for (int i = 0; i < nbSample; i++) {
406
for (int c = 0; c < chan; c++) {
407
switch (ch_route.input_type[c]) {
409
case CH_FRONT_CENTER:
425
out[2] += *in * 0.707;
426
out[3] += *in * 0.707;
432
out[0] += *in * 0.707;
433
out[2] += *in * 0.707;
436
out[1] += *in * 0.707;
437
out[3] += *in * 0.707;
448
static int MDolbyProLogic(float *in,float *out,uint32_t nbSample,uint32_t chan)
450
memset(out, 0, sizeof(float) * nbSample * 2);
452
for (int i = 0; i < nbSample; i++) {
453
for (int c = 0; c < chan; c++) {
454
switch (ch_route.input_type[c]) {
456
case CH_FRONT_CENTER:
458
out[0] += *in * 0.707;
459
out[1] += *in * 0.707;
470
out[0] += DolbyShiftLeft(*in) * 0.707;
471
out[1] += DolbyShiftRight(*in) * 0.707;
474
out[0] += *in * 0.707;
475
out[0] += DolbyShiftLeft(*in) * 0.707 * 0.707;
476
out[1] += DolbyShiftRight(*in) * 0.707 * 0.707;
480
out[0] += DolbyShiftLeft(*in) * 0.707 * 0.707;
481
out[1] += DolbyShiftRight(*in) * 0.707 * 0.707;
492
static int MDolbyProLogic2(float *in,float *out,uint32_t nbSample,uint32_t chan)
494
memset(out, 0, sizeof(float) * nbSample * 2);
496
for (int i = 0; i < nbSample; i++) {
497
for (int c = 0; c < chan; c++) {
498
switch (ch_route.input_type[c]) {
500
case CH_FRONT_CENTER:
502
out[0] += *in * 0.707;
503
out[1] += *in * 0.707;
512
out[0] += DolbyShiftLeft(*in) * 0.707;
513
out[1] += DolbyShiftRight(*in) * 0.707;
516
out[0] += DolbyShiftLeft(*in) * 0.8165;
517
out[1] += DolbyShiftRight(*in) * 0.5774;
520
out[0] += DolbyShiftLeft(*in) * 0.5774;
521
out[1] += DolbyShiftRight(*in) * 0.8165;
524
out[0] += *in * 0.707;
525
out[0] += DolbyShiftLeft(*in) * 0.8165 * 0.707;
526
out[1] += DolbyShiftRight(*in) * 0.5774 * 0.707;
529
out[1] += *in * 0.707;
530
out[0] += DolbyShiftLeft(*in) * 0.5774 * 0.707;
531
out[1] += DolbyShiftRight(*in) * 0.8165 * 0.707;
543
typedef int MIXER(float *in,float *out,uint32_t nbSample,uint32_t chan) ;
545
static MIXER *matrixCall[CHANNEL_LAST] = {
546
NULL, MNto1, MStereo, M2F1R, M3F, M3F1R, M2F2R, M3F2R, M3F2RLFE, MDolbyProLogic, MDolbyProLogic2
548
//_____________________________________________
549
uint32_t AUDMAudioFilterMixer::fill(uint32_t max,float *output,AUD_Status *status)
555
int nbSampleMax=max/_wavHeader.channels;
556
uint8_t input_channels = _previous->getInfo()->channels;
558
// Fill incoming buffer
560
fillIncomingBuffer(status);
561
// Block not filled ?
562
if((_tail-_head)<input_channels)
564
if(*status==AUD_END_OF_STREAM && _head)
566
memset(&_incomingBuffer[_head],0,sizeof(float) * input_channels);
567
_tail=_head+input_channels;
568
printf("[Mixer] Warning asked %u symbols, a window is %u symbols\n",max,window);
582
printf("[Mixer] Warning max %u, channels %u\n",max,input_channels);
584
available=(_tail-_head)/input_channels; // nb Sample
585
ADM_assert(available);
586
if(available > nbSampleMax) available=nbSampleMax;
588
ADM_assert(available);
591
// Now do the downsampling
592
if (_output == CHANNEL_INVALID || ch_route.compareChType(&_wavHeader, _previous->getInfo())) {
594
rd= (uint32_t)MCOPY(&_incomingBuffer[_head],output,available,input_channels);
597
MIXER *call=matrixCall[_output];
598
rd= (uint32_t)call(&_incomingBuffer[_head],output,available,input_channels);
601
_head+=available*input_channels;