1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19------------------------------------------------------------------------------
20
21   PacketVideo Corp.
22   MP3 Decoder Library
23
24   Filename: pvmp3_stereo_proc.cpp
25
26   Functions:
27
28    pvmp3_st_mid_side
29    pvmp3_st_intensity
30    pvmp3_stereo_proc
31
32------------------------------------------------------------------------------
33
34pvmp3_st_mid_side
35
36 INPUT AND OUTPUT DEFINITIONS
37
38Input
39
40   int32 xr[],      input channel
41   int32 xl[],
42   int32 Start,     Location of first element where stereo intensity is applied
43   int32 Number     number of elements affected
44
45 Returns
46
47   int32 xl[],      generated stereo channel
48
49
50------------------------------------------------------------------------------
51
52pvmp3_st_intensity
53
54 INPUT AND OUTPUT DEFINITIONS
55
56Input
57
58   int32 xr[],      input channel
59   int32 xl[],
60   int32 is_pos,    index to table is_ratio_factor[]
61   int32 Start,     Location of first element where stereo intensity is applied
62   int32 Number     number of elements affected
63
64 Returns
65
66   int32 xl[],      generated stereo channel
67
68
69------------------------------------------------------------------------------
70
71pvmp3_stereo_proc
72
73 INPUT AND OUTPUT DEFINITIONS
74
75Input
76
77   int32 xr[],                    input channel
78   int32 xl[],
79   mp3ScaleFactors  *scalefac,    scale factors structure
80   struct gr_info_s *gr_info,     granule structure
81   mp3Header *info                mp3 header info
82 Returns
83
84   int32 xl[],      generated stereo channel
85
86
87------------------------------------------------------------------------------
88 FUNCTION DESCRIPTION
89
90    stereo processing for mpeg1 layer III
91    After requantization, the reconstructed values are processed for ms_stereo
92    or intensity_stereo modes or both, before passing them to the synthesis
93    filterbank
94
95    In ms_stereo mode the values of the normalized middle/side channels
96    M[l] and S[l] are transmitted instead of the left/right channel values
97    L[l] and R[l]. From here, L[l] and R[l] are reconstructed
98
99    Intensity_stereo is done by specifying the magnitude (via the
100    scalefactors of the left channel) and a stereo position is_pos[sfb],
101    which is transmitted instead of scalefactors of the right channel.
102    The stereo position is used to derive the left and right channel signals
103
104------------------------------------------------------------------------------
105 REQUIREMENTS
106
107
108------------------------------------------------------------------------------
109 REFERENCES
110
111 [1] ISO MPEG Audio Subgroup Software Simulation Group (1996)
112     ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension
113
114------------------------------------------------------------------------------
115 PSEUDO-CODE
116
117------------------------------------------------------------------------------
118*/
119
120
121/*----------------------------------------------------------------------------
122; INCLUDES
123----------------------------------------------------------------------------*/
124
125#include "pvmp3_stereo_proc.h"
126#include "pv_mp3dec_fxd_op.h"
127#include "pvmp3_tables.h"
128
129
130/*----------------------------------------------------------------------------
131; MACROS
132; Define module specific macros here
133----------------------------------------------------------------------------*/
134
135
136/*----------------------------------------------------------------------------
137; DEFINES
138; Include all pre-processor statements here. Include conditional
139; compile variables also.
140----------------------------------------------------------------------------*/
141#define N31 31
142
143#define Q31_fmt(a)    (int32(double(0x7FFFFFFF)*a))
144
145/*----------------------------------------------------------------------------
146; LOCAL FUNCTION DEFINITIONS
147; Function Prototype declaration
148----------------------------------------------------------------------------*/
149
150/*----------------------------------------------------------------------------
151; LOCAL STORE/BUFFER/POINTER DEFINITIONS
152; Variable declaration - defined here and used outside this module
153----------------------------------------------------------------------------*/
154/*
155 *  TmpFac= tan(is_pos * (PI /12));
156 *
157 *  TmpFac /= (1 + TmpFac);
158 *
159 */
160
161const int32  is_ratio_factor[8] = {0,
162                                   Q31_fmt(0.21132486540519),   Q31_fmt(0.36602540378444),   Q31_fmt(0.50000000000000),
163                                   Q31_fmt(0.63397459621556),   Q31_fmt(0.78867513459481),   Q31_fmt(1.00000000000000),
164                                   0
165                                  };
166
167/*----------------------------------------------------------------------------
168; EXTERNAL FUNCTION REFERENCES
169; Declare functions defined elsewhere and referenced in this module
170----------------------------------------------------------------------------*/
171
172/*----------------------------------------------------------------------------
173; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
174; Declare variables used in this module but defined elsewhere
175----------------------------------------------------------------------------*/
176
177/*----------------------------------------------------------------------------
178; FUNCTION CODE
179----------------------------------------------------------------------------*/
180
181void pvmp3_st_mid_side(int32 xr[SUBBANDS_NUMBER*FILTERBANK_BANDS],
182                       int32 xl[SUBBANDS_NUMBER*FILTERBANK_BANDS],
183                       int32 Start,
184                       int32 Number)
185{
186
187    int32 *pt_xr  = &xr[Start];
188    int32 *pt_xl  = &xl[Start];
189
190    for (int32 i = Number >> 1; i != 0; i--)
191    {
192        int32 xxr = *(pt_xr) << 1;
193        int32 xxl = *(pt_xl) << 1;
194        *(pt_xr++)  = fxp_mul32_Q32((xxr + xxl), Q31_fmt(0.70710678118655));   /* Sum */
195        *(pt_xl++)  = fxp_mul32_Q32((xxr - xxl), Q31_fmt(0.70710678118655));   /* Diff */
196        xxr = *(pt_xr) << 1;
197        xxl = *(pt_xl) << 1;
198        *(pt_xr++)  = fxp_mul32_Q32((xxr + xxl), Q31_fmt(0.70710678118655));   /* Sum */
199        *(pt_xl++)  = fxp_mul32_Q32((xxr - xxl), Q31_fmt(0.70710678118655));   /* Diff */
200    }
201
202
203    if (Number&1)
204    {
205        int32 xxr = *(pt_xr) << 1;
206        int32 xxl = *(pt_xl) << 1;
207        *(pt_xr)  = fxp_mul32_Q32((xxr + xxl), Q31_fmt(0.70710678118655));   /* Sum */
208        *(pt_xl)  = fxp_mul32_Q32((xxr - xxl), Q31_fmt(0.70710678118655));   /* Diff */
209    }
210
211}
212
213
214/*----------------------------------------------------------------------------
215; FUNCTION CODE
216----------------------------------------------------------------------------*/
217
218void pvmp3_st_intensity(int32 xr[SUBBANDS_NUMBER*FILTERBANK_BANDS],
219                        int32 xl[SUBBANDS_NUMBER*FILTERBANK_BANDS],
220                        int32 is_pos,
221                        int32 Start,
222                        int32 Number)
223{
224
225    int32 TmpFac = is_ratio_factor[ is_pos & 7];
226
227    int32 *pt_xr  = &xr[Start];
228    int32 *pt_xl  = &xl[Start];
229
230    for (int32 i = Number >> 1; i != 0; i--)
231    {
232        int32 tmp = fxp_mul32_Q32((*pt_xr) << 1, TmpFac);
233        *(pt_xl++) = (*pt_xr) - tmp;
234        *(pt_xr++) = tmp;
235        tmp = fxp_mul32_Q32((*pt_xr) << 1, TmpFac);
236        *(pt_xl++) = (*pt_xr) - tmp;
237        *(pt_xr++) = tmp;
238    }
239
240    if (Number&1)
241    {
242        int32 tmp = fxp_mul32_Q32((*pt_xr) << 1, TmpFac);
243        *(pt_xl) = (*pt_xr) - tmp;
244        *(pt_xr) = tmp;
245    }
246
247}
248
249/*----------------------------------------------------------------------------
250; FUNCTION CODE
251----------------------------------------------------------------------------*/
252void pvmp3_stereo_proc(int32 xr[SUBBANDS_NUMBER*FILTERBANK_BANDS],
253                       int32 xl[SUBBANDS_NUMBER*FILTERBANK_BANDS],
254                       mp3ScaleFactors *scalefac,
255                       granuleInfo *gr_info,
256                       int32 used_freq_lines,
257                       mp3Header *info)
258{
259
260
261    int32 sb;
262    int32 ss;
263    int32 sfbNo;
264    int32 sfbStart;
265
266    int32 sfb;
267    int32 sfbTemp;
268    int32 i;
269    int32 j;
270
271
272    int32 i_stereo  = (info->mode == MPG_MD_JOINT_STEREO) &&
273                      (info->mode_ext & 0x1);
274
275    int32 ms_stereo = (info->mode == MPG_MD_JOINT_STEREO) &&
276                      (info->mode_ext & 0x2);
277
278    int32 sfreq  = info->version_x + (info->version_x << 1);
279    sfreq += info->sampling_frequency;
280
281
282
283
284    if (i_stereo)
285    {
286        if (gr_info->window_switching_flag && (gr_info->block_type == 2))
287        {
288            if (gr_info->mixed_block_flag)
289            {
290                /*
291                 * mixed blocks processing
292                 */
293                i = 31;
294                ss = 17;
295                sb = 0;
296                while (i >= 0)
297                {
298                    if (xl[(i*FILTERBANK_BANDS) + ss])
299                    {
300                        sb = (i << 4) + (i << 1) + ss;
301                        i = -1;
302                    }
303                    else
304                    {
305                        ss--;
306                        if (ss < 0)
307                        {
308                            i--;
309                            ss = 17;
310                        }
311                    }
312                }
313
314                if (sb < 36)
315                {
316                    /*
317                     * mixed blocks processing: intensity bound inside long blocks
318                     */
319                    /* 1. long blocks up to intensity border: not intensity */
320
321                    if (mp3_sfBandIndex[sfreq].l[4] <= sb)
322                    {
323                        sfb = 4;
324                    }
325                    else
326                    {
327                        sfb = 0;
328                    }
329
330                    while (mp3_sfBandIndex[sfreq].l[sfb] < sb)
331                    {
332                        sfb++;
333                    }
334
335                    /* from that sfb on intensity stereo */
336                    sfbTemp = sfb;  /* save for later use */
337
338                    sfbStart = mp3_sfBandIndex[sfreq].l[sfb];
339
340                    /* from 0 up to sfbStart do ms_stereo or normal stereo */
341
342                    if (ms_stereo)
343                    {
344                        pvmp3_st_mid_side(xr, xl, 0, sfbStart);
345                    }
346
347                    /* 2. long blocks from intensity border up to sfb band 8: intensity */
348                    /* calc. is_ratio */
349
350
351                    /* Start of intensity stereo of remaining sfc bands: */
352                    for (; sfbTemp < 8; sfbTemp++)
353                    {
354                        sfbStart = mp3_sfBandIndex[sfreq].l[sfbTemp];  /* = Start in 0 ... 575 */
355                        sfbNo = mp3_sfBandIndex[sfreq].l[sfbTemp+1] - mp3_sfBandIndex[sfreq].l[sfbTemp]; /* No of lines to process */
356
357                        if (scalefac->l[sfbTemp] != 7)
358                        {
359                            pvmp3_st_intensity(xr, xl, scalefac->l[sfbTemp], sfbStart, sfbNo);
360                        }
361                        else if (ms_stereo)
362                        {
363                            pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
364                        }
365
366                    }  /* for (; sfbTemp < 8; sfbTemp++) */
367
368                    for (j = 0; j < 3; j++)
369                    {
370                        /* 3. short blocks from sfbcnt to last sfb do intensity stereo */
371                        for (sfbTemp = 3; sfbTemp < 13; sfbTemp++)
372                        {
373                            sfbNo = mp3_sfBandIndex[sfreq].s[sfbTemp+1] - mp3_sfBandIndex[sfreq].s[sfbTemp]; /* No of lines to process */
374                            sfbStart = 3 * mp3_sfBandIndex[sfreq].s[sfbTemp] + j * sfbNo;
375
376                            if (scalefac->s[j][sfbTemp] != 7)
377                            {
378                                pvmp3_st_intensity(xr, xl, scalefac->s[j][sfbTemp], sfbStart, sfbNo);
379                            }
380                            else if (ms_stereo)
381                            {
382                                pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
383                            }
384
385                        }  /* for (; sfbTemp < 22; sfbTemp++) */
386                    } /* for (j = 0; j < 3; j++) */
387                }
388                else   /* else for (sb >= 36) */
389                {
390                    /*
391                     * mixed blocks processing: intensity bound outside long blocks
392                     */
393
394
395                    /*
396                     * 2. short blocks from sfb band 3 up to intensity border: normal stereo, ms stereo and intensity
397                     */
398                    for (j = 0; j < 3; j++)
399                    {
400                        int32 sfbcnt;
401                        sfbcnt = -1;
402
403                        for (sfb = 12; sfb >= 3; sfb--)
404                        {
405                            int32 lines;
406                            lines = mp3_sfBandIndex[sfreq].s[sfb+1] - mp3_sfBandIndex[sfreq].s[sfb];
407                            i = 3 * mp3_sfBandIndex[sfreq].s[sfb] + (j + 1) * lines - 1;
408
409                            while (lines > 0)
410                            {
411                                if (xl[i])
412                                {
413                                    sfbcnt = sfb;
414                                    sfb = -10;
415                                    lines = -10;
416                                }
417                                lines--;
418                                i--;
419                            }
420                        }
421
422                        sfbcnt += 1;
423                        if (sfbcnt < 3)
424                        {
425                            sfbcnt = 3;
426                        }
427
428                        sfbTemp = sfbcnt;        /* for later use */
429
430
431                        /*
432                         *   do normal stereo or MS stereo from sfb 3 to < sfbcnt:
433                         */
434                        for (sb = 3; sb < sfbcnt; sb++)
435                        {
436                            sfbNo = mp3_sfBandIndex[sfreq].s[sb+1] - mp3_sfBandIndex[sfreq].s[sb];
437                            sfbStart = 3 * mp3_sfBandIndex[sfreq].s[sb] + j * sfbNo;
438
439                            if (ms_stereo)
440                            {
441                                pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
442                            }
443
444                        }
445
446                        /* from sfbcnt to last sfb do intensity stereo */
447                        for (; sfbTemp < 13; sfbTemp++)
448                        {
449                            sfbNo = mp3_sfBandIndex[sfreq].s[sfbTemp+1] - mp3_sfBandIndex[sfreq].s[sfbTemp]; /* No of lines to process */
450                            sfbStart = 3 * mp3_sfBandIndex[sfreq].s[sfbTemp] + j * sfbNo;
451
452                            if (scalefac->s[j][sfbTemp] != 7)
453                            {
454                                pvmp3_st_intensity(xr, xl, scalefac->s[j][sfbTemp], sfbStart, sfbNo);
455                            }
456                            else if (ms_stereo)
457                            {
458                                pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
459                            }
460
461                        }  /* for (; sfbTemp < 22; sfbTemp++) */
462
463                    } /* for (j = 0; j < 3; j++) */
464
465                    /* 1. long blocks up to sfb band 8: not intensity */
466                    /* from 0 to sfb 8 ms_stereo or normal stereo */
467
468                    sfbStart = mp3_sfBandIndex[sfreq].l[8];
469
470                    if (ms_stereo)
471                    {
472                        pvmp3_st_mid_side(xr, xl, 0, sfbStart);
473                    }
474
475                }
476            }  /* if (gr_info->mixed_block_flag) */
477            else
478            {
479                /*
480                 * short block processing
481                 */
482                for (j = 0; j < 3; j++)
483                {
484                    int32 sfbcnt = -1;
485
486                    for (sfb = 12; sfb >= 0; sfb--)
487                    {
488                        int32 lines = mp3_sfBandIndex[sfreq].s[sfb+1] - mp3_sfBandIndex[sfreq].s[sfb];
489                        i = 3 * mp3_sfBandIndex[sfreq].s[sfb] + (j + 1) * lines - 1;
490
491                        while (lines > 0)
492                        {
493                            if (xl[i])
494                            {
495                                sfbcnt = sfb;
496                                sfb = -10;
497                                lines = -10;
498                            }
499                            lines--;
500                            i--;
501                        }
502                    }
503
504                    sfbcnt += 1;
505                    sfbTemp = sfbcnt;        /* for later use */
506
507                    /* do normal stereo or MS stereo from 0 to sfbcnt */
508                    for (sb = 0; sb < sfbcnt; sb++)
509                    {
510                        sfbNo = mp3_sfBandIndex[sfreq].s[sb+1] - mp3_sfBandIndex[sfreq].s[sb];
511                        sfbStart = 3 * mp3_sfBandIndex[sfreq].s[sb] + j * sfbNo;
512
513                        if (ms_stereo)
514                        {
515                            pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
516                        }
517                    }
518
519
520                    /* from sfbcnt to last sfb do intensity stereo */
521                    for (; sfbTemp < 13; sfbTemp++)
522                    {
523                        sfbNo = mp3_sfBandIndex[sfreq].s[sfbTemp+1] - mp3_sfBandIndex[sfreq].s[sfbTemp]; /* No of lines to process */
524                        sfbStart = 3 * mp3_sfBandIndex[sfreq].s[sfbTemp] + j * sfbNo;
525
526                        if (scalefac->s[j][sfbTemp] != 7)
527                        {
528                            pvmp3_st_intensity(xr, xl, scalefac->s[j][sfbTemp], sfbStart, sfbNo);
529                        }
530                        else if (ms_stereo)
531                        {
532                            pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
533                        }
534
535                    }  /* for (; sfbTemp < 22; sfbTemp++) */
536
537                } /* for (j = 0; j < 3; j++) */
538
539            } /* if( gr_info->mixed_block_flag) */
540
541
542
543        }  /* if (gr_info->window_switching_flag && (gr_info->block_type == 2)) */
544        else
545        {
546            /*
547             *   long block processing
548             */
549            i = 31;
550            ss = 17;
551            sb = 0;
552
553            while (i >= 0)
554            {
555                if (xl[(i*FILTERBANK_BANDS) + ss] != 0)
556                {
557                    sb = (i << 4) + (i << 1) + ss;
558                    i = -2;
559                }
560                else
561                {
562                    ss--;
563                    if (ss < 0)
564                    {
565                        i--;
566                        ss = 17;
567                    }
568                }
569            }
570
571            if (sb)
572            {
573                if (mp3_sfBandIndex[sfreq].l[14] <= sb)
574                {
575                    sfb = 14;
576                }
577                else if (mp3_sfBandIndex[sfreq].l[7] <= sb)
578                {
579                    sfb = 7;
580                }
581                else
582                {
583                    sfb = 0;
584                }
585
586
587                while (mp3_sfBandIndex[sfreq].l[sfb] <= sb)
588                {
589                    sfb++;
590                }
591            }
592            else
593            {
594                if (i == -1)
595                {
596                    /*  all xr[1][][] are 0: set IS bound sfb to 0  */
597                    sfb = 0;
598                }
599                else
600                {
601                    /*  xr[1][0][0] is unequal 0 and all others are 0: set IS bound sfb to 1 */
602                    sfb = 1;
603                }
604            }
605
606            sfbTemp = sfb;  /* save for later use */
607
608
609            sfbStart = mp3_sfBandIndex[sfreq].l[sfb];
610
611            /* from 0 to sfbStart ms_stereo or normal stereo */
612            if (ms_stereo)
613            {
614                pvmp3_st_mid_side(xr, xl, 0, sfbStart);
615            }
616
617            /* now intensity stereo of the remaining sfb's: */
618            for (; sfb < 21; sfb++)
619            {
620                sfbStart = mp3_sfBandIndex[sfreq].l[sfb];
621                sfbNo = mp3_sfBandIndex[sfreq].l[sfb+1] - mp3_sfBandIndex[sfreq].l[sfb]; /* No of lines to process */
622
623                if (scalefac->l[sfb] != 7)
624                {
625                    pvmp3_st_intensity(xr, xl, scalefac->l[sfb], sfbStart, sfbNo);
626                }
627                else if (ms_stereo)
628                {
629                    pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
630                }
631
632            }  /* for (; sfbTemp < 22; sfbTemp++) */
633
634
635
636            sfbStart = mp3_sfBandIndex[sfreq].l[21];
637            sfbNo = mp3_sfBandIndex[sfreq].l[22] - mp3_sfBandIndex[sfreq].l[21]; /* No of lines to process */
638
639            if (scalefac->l[21] != 7)
640            {
641                if (sfbTemp < 21)
642                {
643                    sfbTemp = scalefac->l[20];
644                }
645                else
646                {
647                    sfbTemp = 0;  /* if scalefac[20] is not an intensity position, is_pos = 0 */
648                }
649
650                pvmp3_st_intensity(xr, xl, sfbTemp, sfbStart, sfbNo);
651            }
652            else if (ms_stereo)
653            {
654                pvmp3_st_mid_side(xr, xl, sfbStart, sfbNo);
655            }
656
657        }  /* if (gr_info->window_switching_flag && (gr_info->block_type == 2)) */
658
659
660    }  /* if (i_stereo)  */
661    else
662    {
663        /*
664         * normal or ms stereo processing
665         */
666        if (ms_stereo)
667        {
668
669            pvmp3_st_mid_side(xr, xl, 0, used_freq_lines);
670
671        }
672
673    } /* if (i_stereo) */
674
675}
676
677