12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* ----------------------------------------------------------------------------------------------------------- 32228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSoftware License for The Fraunhofer FDK AAC Codec Library for Android 42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi� Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V. 62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project All rights reserved. 72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1. INTRODUCTION 92228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 112228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is intended to be used on a wide variety of Android devices. 122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 132228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectaudio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindependent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof the MPEG specifications. 172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 182228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPatent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmay be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindividually for the purpose of encoding or decoding bit streams in products that are compliant with 212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthese patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware may already be covered under those patent licenses when it is used for those licensed purposes only. 242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCommercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectare also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectapplications information and documentation. 282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project2. COPYRIGHT LICENSE 302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectRedistribution and use in source and binary forms, with or without modification, are permitted without 322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpayment of copyright license fees provided that you satisfy the following conditions: 332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 342228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in redistributions of the FDK AAC Codec or 352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectyour modifications thereto in source code form. 362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 372228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in the documentation and/or other materials 382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprovided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 392228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must make available free of charge copies of the complete source code of the FDK AAC Codec and your 402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmodifications thereto to recipients of copies in binary form. 412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe name of Fraunhofer may not be used to endorse or promote products derived from this library without 432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprior written permission. 442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 452228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware or your modifications thereto. 472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 482228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYour modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectand the date of any change. For modified versions of the FDK AAC Codec, the term 502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project3. NO PATENT LICENSE 542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 552228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectNO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 562228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectrespect to this software. 582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 592228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectby appropriate patent licenses. 612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project4. DISCLAIMER 632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 642228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectincluding but not limited to procurement of substitute goods or services; loss of use, data, or profits, 692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projector business interruption, however caused and on any theory of liability, whether in contract, strict 702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectliability, or tort (including negligence), arising in any way out of the use of this software, even if 712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectadvised of the possibility of such damage. 722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project5. CONTACT INFORMATION 742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 752228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFraunhofer Institute for Integrated Circuits IIS 762228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAttention: Audio and Multimedia Departments - FDK AAC LL 772228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAm Wolfsmantel 33 782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project91058 Erlangen, Germany 792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectwww.iis.fraunhofer.de/amm 812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectamm-info@iis.fraunhofer.de 822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project----------------------------------------------------------------------------------------------------------- */ 832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/**************************** FDK PCM utils module ************************** 852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Author(s): Christian Griebel 8747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Description: Defines functions that perform downmixing or a simple channel 8847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi expansion in the PCM time domain. 892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*******************************************************************************/ 912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "pcmutils_lib.h" 932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "genericStds.h" 952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "fixpoint_math.h" 9647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#include "FDK_core.h" 9747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 9847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 9947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* ------------------------ * 10047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * GLOBAL SETTINGS (GFR): * 10147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * ------------------------ */ 10247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define DSE_METADATA_ENABLE /*!< Enable this to support MPEG/ETSI DVB ancillary data for 10347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi encoder assisted downmixing of MPEG-4 AAC and 10447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi MPEG-1/2 layer 2 streams. */ 10547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCE_METADATA_ENABLE /*!< Enable this to support MPEG matrix mixdown with a 10647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi coefficient carried in the PCE. */ 10747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 10847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCM_DMX_MAX_IN_CHANNELS ( 8 ) /* Neither the maximum number of input nor the maximum number of output channels ... */ 10947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCM_DMX_MAX_OUT_CHANNELS ( 8 ) /* ... must exceed the maximum number of channels that the framework can handle. */ 11047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 11147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* ------------------------ * 11247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * SPECIFIC SETTINGS: * 11347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * ------------------------ */ 11447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCM_CHANNEL_EXTENSION_ENABLE /*!< Allow module to duplicate mono signals or add zero channels to achieve the 11547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi desired number of output channels. */ 11647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 11747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCM_DMX_DFLT_MAX_OUT_CHANNELS ( 6 ) /*!< The maximum number of output channels. If the value is greater than 0 the module 11847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi will automatically create a mixdown for all input signals with more channels 11947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi than specified. */ 12047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCM_DMX_DFLT_MIN_OUT_CHANNELS ( 0 ) /*!< The minimum number of output channels. If the value is greater than 0 the module 12147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi will do channel extension automatically for all input signals with less channels 12247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi than specified. */ 12347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCM_DMX_MAX_DELAY_FRAMES ( 1 ) /*!< The maximum delay frames to align the bitstreams payload with the PCM output. */ 12447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCM_DMX_DFLT_EXPIRY_FRAME ( 50 ) /*!< If value is greater than 0 the mixdown coefficients will expire by default after the 12547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi given number of frames. The value 50 corresponds to at least 500ms (FL 960 @ 96kHz) */ 12647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* #define PCMDMX_DEBUG */ 12747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 12847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* Derived setting: 12947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * No need to edit beyond this line. */ 13047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if defined(DSE_METADATA_ENABLE) || defined(PCE_METADATA_ENABLE) || defined(ARIB_MIXDOWN_ENABLE) 13147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DOWNMIX_ENABLE /*!< Generally enable down mixing. */ 13247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 13347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_IN_CHANNELS > 2) || (PCM_DMX_MAX_OUT_CHANNELS > 2) 13447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_CHANNELS ( 8 ) 13547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_CHANNEL_GROUPS ( 4 ) 13647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_CHANNELS_PER_GROUP PCM_DMX_MAX_CHANNELS /* All channels can be in one group */ 13747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#else 13847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_CHANNELS ( 3 ) /* Need to add 1 because there are three channel positions in first channel group. */ 13947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_CHANNEL_GROUPS ( 1 ) /* Only front channels supported. */ 14047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_CHANNELS_PER_GROUP ( 2 ) /* The maximum over all channel groups */ 14147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 14247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_IN_CHANNELS > PCM_DMX_MAX_OUT_CHANNELS) 14347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_IO_CHANNELS PCM_DMX_MAX_IN_CHANNELS 14447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#else 14547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define PCM_DMX_MAX_IO_CHANNELS PCM_DMX_MAX_OUT_CHANNELS 14647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* Decoder library info */ 1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define PCMDMX_LIB_VL0 2 1504f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi#define PCMDMX_LIB_VL1 4 151603f48ab99ce76f552f4f6f85d06b8c5b94c698eJean-Michel Trivi#define PCMDMX_LIB_VL2 2 1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define PCMDMX_LIB_TITLE "PCM Downmix Lib" 1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define PCMDMX_LIB_BUILD_DATE __DATE__ 1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define PCMDMX_LIB_BUILD_TIME __TIME__ 1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* Fixed and unique channel group indices. 1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * The last group index has to be smaller than PCM_DMX_MAX_CHANNEL_GROUPS. */ 1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define CH_GROUP_FRONT ( 0 ) 1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define CH_GROUP_SIDE ( 1 ) 1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define CH_GROUP_REAR ( 2 ) 1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define CH_GROUP_LFE ( 3 ) 1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* The ordering of the following fixed channel labels has to be in MPEG-4 style. 1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * From the center to the back with left and right channel interleaved (starting with left). 1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * The last channel label index has to be smaller than PCM_DMX_MAX_CHANNELS. */ 1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define CENTER_FRONT_CHANNEL ( 0 ) /* C */ 1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define LEFT_FRONT_CHANNEL ( 1 ) /* L */ 1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define RIGHT_FRONT_CHANNEL ( 2 ) /* R */ 17047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define LEFT_REAR_CHANNEL ( 3 ) /* Lr (aka left back channel) or center back channel */ 17147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define RIGHT_REAR_CHANNEL ( 4 ) /* Rr (aka right back channel) */ 17247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define LOW_FREQUENCY_CHANNEL ( 5 ) /* Lf */ 17347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define LEFT_MULTIPRPS_CHANNEL ( 6 ) /* Left multipurpose channel */ 17447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define RIGHT_MULTIPRPS_CHANNEL ( 7 ) /* Right multipurpose channel */ 1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* More constants */ 17747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define ONE_CHANNEL ( 1 ) 1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define TWO_CHANNEL ( 2 ) 17947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define SIX_CHANNEL ( 6 ) 18047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define EIGHT_CHANNEL ( 8 ) 18147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 18247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCMDMX_A_IDX_DEFAULT ( 2 ) 18347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCMDMX_B_IDX_DEFAULT ( 2 ) 18447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCMDMX_LFE_IDX_DEFAULT ( 15 ) 18547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCMDMX_GAIN_5_DEFAULT ( 0 ) 18647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCMDMX_GAIN_2_DEFAULT ( 0 ) 18747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 18847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCMDMX_MAX_HEADROOM ( 3 ) /* Defines the maximum PCM scaling headroom that can be done by a 18947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi postprocessing step. This value must be greater or equal to 0. */ 19047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 19147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define FALSE 0 19247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define TRUE 1 19347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define IN 0 19447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define OUT 1 19547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 19647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* Type definitions: */ 19747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifndef DMX_HIGH_PRECISION_ENABLE 19847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FIXP_DMX FIXP_SGL 19947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DMX2FX_DBL(x) FX_SGL2FX_DBL((FIXP_SGL)(x)) 20047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DBL2FX_DMX(x) FX_DBL2FX_SGL(x) 20147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FL2FXCONST_DMX(x) FL2FXCONST_SGL(x) 20247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define MAXVAL_DMX MAXVAL_SGL 20347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DMX2SHRT(x) ((SHORT)(x)) 20447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DMX2FL(x) FX_DBL2FL(FX_DMX2FX_DBL(x)) 20547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#else 20647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FIXP_DMX FIXP_DBL 20747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DMX2FX_DBL(x) ((FIXP_DBL)(x)) 20847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DBL2FX_DMX(x) ((FIXP_DBL)(x) 20947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FL2FXCONST_DMX(x) FL2FXCONST_DBL(x) 21047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define MAXVAL_DMX MAXVAL_DBL 21147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DMX2SHRT(x) ((SHORT)((x)>>FRACT_BITS)) 21247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #define FX_DMX2FL(x) FX_DBL2FL(x) 21347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* The number of channels positions for each group in the internal representation. 21647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * See the channel labels above. */ 21747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic const UCHAR maxChInGrp[PCM_DMX_MAX_CHANNEL_GROUPS] = { 21847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNELS > 3) 21947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 3, 0, 2, 1 22047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#else 22147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_MAX_CHANNELS_PER_GROUP 22247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 22347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi}; 2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* List of packed channel modes */ 2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projecttypedef enum 22747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ /* CH_MODE_<numFrontCh>_<numSideCh>_<numBackCh>_<numLfCh> */ 2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_UNDEFINED = 0x0000, 2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1 channel */ 2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_1_0_0_0 = 0x0001, /* chCfg 1 */ 2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2 channels */ 2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_0_0_0 = 0x0002, /* chCfg 2 */ 2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 3 channels */ 2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_0_0_0 = 0x0003, /* chCfg 3 */ 2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_0_1_0 = 0x0102, 2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_0_0_1 = 0x1002, 2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 4 channels */ 2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_0_1_0 = 0x0103, /* chCfg 4 */ 2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_0_2_0 = 0x0202, 2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_0_1_1 = 0x1102, 24147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_4_0_0_0 = 0x0004, 2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5 channels */ 2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_0_2_0 = 0x0203, /* chCfg 5 */ 2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_0_2_1 = 0x1202, 2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_0_1_1 = 0x1103, 2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_2_0_0 = 0x0023, 24747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_5_0_0_0 = 0x0005, 2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6 channels */ 2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_0_2_1 = 0x1203, /* chCfg 6 */ 25047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_2_0_1 = 0x1023, 2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_2_1_0 = 0x0123, 25247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_5_0_1_0 = 0x0105, 25347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_6_0_0_0 = 0x0006, 2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 7 channels */ 2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_2_2_1 = 0x1222, 25647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_0_3_1 = 0x1303, /* chCfg 11 */ 2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_2_1_1 = 0x1123, 2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_2_2_0 = 0x0223, 25947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_0_2_2 = 0x2203, 26047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_5_0_2_0 = 0x0205, 26147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_5_0_1_1 = 0x1105, 26247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_7_0_0_0 = 0x0007, 2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 8 channels */ 26447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_2_2_1 = 0x1223, 26547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_0_4_1 = 0x1403, /* chCfg 12 */ 26647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_5_0_2_1 = 0x1205, /* chCfg 7 + 14 */ 26747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_5_2_1_0 = 0x0125, 2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_2_1_2 = 0x2123, 26947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_2_2_2_2 = 0x2222, 27047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_0_3_2 = 0x2303, 27147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_8_0_0_0 = 0x0008 2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} PCM_DMX_CHANNEL_MODE; 2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* These are the channel configurations linked to 2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the number of output channels give by the user: */ 27847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic const PCM_DMX_CHANNEL_MODE outChModeTable[PCM_DMX_MAX_CHANNELS+1] = 2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 28047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_UNDEFINED, 2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_1_0_0_0, /* 1 channel */ 2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_2_0_0_0, /* 2 channels */ 28347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_0_0_0 /* 3 channels */ 28447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNELS > 3) 28547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ,CH_MODE_3_0_1_0, /* 4 channels */ 2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_0_2_0, /* 5 channels */ 2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project CH_MODE_3_0_2_1, /* 6 channels */ 28847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_0_3_1, /* 7 channels */ 28947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CH_MODE_3_0_4_1 /* 8 channels */ 29047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}; 2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 29347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic const FIXP_DMX abMixLvlValueTab[8] = 2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 29547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.500f), /* scaled by 1 */ 29647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.841f), 29747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.707f), 29847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.596f), 29947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.500f), 30047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.422f), 30147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.355f), 30247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.0f) 30347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi}; 30447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 30547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic const FIXP_DMX lfeMixLvlValueTab[16] = 30647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ /* value, scale */ 30747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.7905f), /* 2 */ 30847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.5000f), /* 2 */ 30947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.8395f), /* 1 */ 31047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.7065f), /* 1 */ 31147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.5945f), /* 1 */ 31247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.500f), /* 1 */ 31347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.841f), /* 0 */ 31447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.707f), /* 0 */ 31547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.596f), /* 0 */ 31647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.500f), /* 0 */ 31747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.316f), /* 0 */ 31847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.178f), /* 0 */ 31947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.100f), /* 0 */ 32047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.032f), /* 0 */ 32147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.010f), /* 0 */ 32247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.000f) /* 0 */ 3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}; 3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 32647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 32747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCE_METADATA_ENABLE 3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* MPEG matrix mixdown: 3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Set 1: L' = (1 + 2^-0.5 + A )^-1 * [L + C * 2^-0.5 + A * Ls]; 3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project R' = (1 + 2^-0.5 + A )^-1 * [R + C * 2^-0.5 + A * Rs]; 3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Set 2: L' = (1 + 2^-0.5 + 2A )^-1 * [L + C * 2^-0.5 - A * (Ls + Rs)]; 3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project R' = (1 + 2^-0.5 + 2A )^-1 * [R + C * 2^-0.5 + A * (Ls + Rs)]; 3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project M = (3 + 2A)^-1 * [L + C + R + A*(Ls + Rs)]; 3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 33747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi static const FIXP_DMX mpegMixDownIdx2Coef[4] = 3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 33947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.70710678f), 34047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.5f), 34147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.35355339f), 34247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.0f) 3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project }; 3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 34547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi static const FIXP_SGL mpegMixDownIdx2PreFact[3][4] = 34647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { { /* Set 1: */ 34747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.4142135623730950f), 34847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.4530818393219728f), 34947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.4852813742385703f), 35047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.5857864376269050f) 35147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi },{ /* Set 2: */ 35247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.3203772410170407f), 35347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.3693980625181293f), 35447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.4142135623730950f), 35547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.5857864376269050f) 35647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi },{ /* Mono DMX set: */ 35747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.2265409196609864f), 35847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.25f), 35947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.2697521433898179f), 36047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DMX(0.3333333333333333f) } 3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project }; 36247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* PCE_METADATA_ENABLE */ 3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 36547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define TYPE_NONE ( 0x0 ) 36647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define TYPE_DSE_DATA ( 0x1 ) 36747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define TYPE_PCE_DATA ( 0x2 ) 3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projecttypedef struct 3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 37147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT typeFlags; 37247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* From DSE */ 37347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR cLevIdx; 37447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR sLevIdx; 37547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR dmixIdxA; 37647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR dmixIdxB; 37747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR dmixIdxLfe; 37847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR dmxGainIdx2; 37947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR dmxGainIdx5; 38047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCE_METADATA_ENABLE 38147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* From PCE */ 38247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR matrixMixdownIdx; 38347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 38447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Attributes: */ 38547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi SCHAR pseudoSurround; /*!< If set to 1 the signal is pseudo surround compatible. The value 0 tells 38647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi that it is not. If the value is -1 the information is not available. */ 38747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT expiryCount; /*!< Counter to monitor the life time of a meta data set. */ 38847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 38947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} DMX_BS_META_DATA; 39047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 39147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* Default metadata */ 39247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic const DMX_BS_META_DATA dfltMetaData = { 39347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 0, 2, 2, 2, 2, 15, 0, 0, 39447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCE_METADATA_ENABLE 39547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 0, 39647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 39747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi -1, 0 39847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi}; 3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 40047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* Dynamic (user) params: 40147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi See the definition of PCMDMX_PARAM for details on the specific fields. */ 40247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivitypedef struct 40347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 40447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT expiryFrame; /*!< Linked to DMX_BS_DATA_EXPIRY_FRAME */ 40547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi DUAL_CHANNEL_MODE dualChannelMode; /*!< Linked to DMX_DUAL_CHANNEL_MODE */ 40647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PSEUDO_SURROUND_MODE pseudoSurrMode; /*!< Linked to DMX_PSEUDO_SURROUND_MODE */ 40747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi SHORT numOutChannelsMin; /*!< Linked to MIN_NUMBER_OF_OUTPUT_CHANNELS */ 40847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi SHORT numOutChannelsMax; /*!< Linked to MAX_NUMBER_OF_OUTPUT_CHANNELS */ 40947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR frameDelay; /*!< Linked to DMX_BS_DATA_DELAY */ 4102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 41147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} PCM_DMX_USER_PARAMS; 4122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* Modules main data structure: */ 4142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstruct PCM_DMX_INSTANCE 4152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 41647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Metadata */ 41747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi DMX_BS_META_DATA bsMetaData[PCM_DMX_MAX_DELAY_FRAMES+1]; 41847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_USER_PARAMS userParams; 41947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 42047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR applyProcessing; /*!< Flag to en-/disable modules processing. 42147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi The max channel limiting is done independently. */ 4222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}; 4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* Memory allocation macro */ 4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectC_ALLOC_MEM_STATIC(PcmDmxInstance, struct PCM_DMX_INSTANCE, 1) 4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 42847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/** Evaluate a given channel configuration and extract a packed channel mode. In addition the 42947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * function generates a channel offset table for the mapping to the internal representation. 4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * This function is the inverse to the getChannelDescription() routine. 4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] The total number of channels of the given configuration. 4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Array holding the corresponding channel types for each channel. 4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Array holding the corresponding channel type indices for each channel. 4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [out] Array where the buffer offsets for each channel are stored into. 43547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [out] The generated packed channel mode that represents the given input configuration. 43647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @returns Returns an error code. 4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic 43947c680c62246594107da0a8995c953dfb8040bceJean-Michel TriviPCMDMX_ERROR getChannelMode ( 4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const INT numChannels, /* in */ 4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const AUDIO_CHANNEL_TYPE channelType[], /* in */ 4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const UCHAR channelIndices[], /* in */ 44347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR offsetTable[PCM_DMX_MAX_CHANNELS], /* out */ 44447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_CHANNEL_MODE *chMode /* out */ 4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR chIdx[PCM_DMX_MAX_CHANNEL_GROUPS][PCM_DMX_MAX_CHANNELS_PER_GROUP]; 44847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR numChInGrp[PCM_DMX_MAX_CHANNEL_GROUPS]; /* Total num of channels per group of the input config */ 44947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR numChFree[PCM_DMX_MAX_CHANNEL_GROUPS]; /* Number of free slots per group in the internal repr. */ 45047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR hardToPlace[PCM_DMX_MAX_CHANNELS]; /* List of channels not matching the internal repr. */ 45147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR h2pSortIdx[PCM_DMX_MAX_CHANNELS]; 45247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCMDMX_ERROR err = PCMDMX_OK; 45347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int ch, grpIdx; 45447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int numChToPlace = 0; 4552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(channelType != NULL); 4572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(channelIndices != NULL); 4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(offsetTable != NULL); 45947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(chMode != NULL); 4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* For details see ISO/IEC 13818-7:2005(E), 8.5.3 Channel configuration */ 4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemclear(numChInGrp, PCM_DMX_MAX_CHANNEL_GROUPS*sizeof(UCHAR)); 4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemset(offsetTable, 255, PCM_DMX_MAX_CHANNELS*sizeof(UCHAR)); 4646ab36997af5d5acda4f21d33031f4e45c85f96b7Jean-Michel Trivi FDKmemset(chIdx, 255, PCM_DMX_MAX_CHANNEL_GROUPS*PCM_DMX_MAX_CHANNELS_PER_GROUP*sizeof(UCHAR)); 46547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemset(hardToPlace, 255, PCM_DMX_MAX_CHANNELS*sizeof(UCHAR)); 46647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemset(h2pSortIdx, 255, PCM_DMX_MAX_CHANNELS*sizeof(UCHAR)); 46747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Get the restrictions of the internal representation */ 46847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(numChFree, maxChInGrp, PCM_DMX_MAX_CHANNEL_GROUPS*sizeof(UCHAR)); 46947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 47047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *chMode = CH_MODE_UNDEFINED; 4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Categorize channels */ 4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (ch = 0; ch < numChannels; ch += 1) { 47447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR chGrpIdx = channelIndices[ch]; 47547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int i = 0, j; 4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (channelType[ch]) { 4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ACT_FRONT_TOP: 47947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chGrpIdx += numChInGrp[CH_GROUP_FRONT]; /* Append after normal plain */ 48047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case ACT_FRONT: 4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grpIdx = CH_GROUP_FRONT; 4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 48347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNEL_GROUPS > 1) 4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ACT_SIDE_TOP: 48547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chGrpIdx += numChInGrp[CH_GROUP_SIDE]; /* Append after normal plain */ 48647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case ACT_SIDE: 4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grpIdx = CH_GROUP_SIDE; 4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ACT_BACK_TOP: 49047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chGrpIdx += numChInGrp[CH_GROUP_REAR]; /* Append after normal plain */ 49147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case ACT_BACK: 4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grpIdx = CH_GROUP_REAR; 4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case ACT_LFE: 4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grpIdx = CH_GROUP_LFE; 4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 49747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 49947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Found a channel that can not be categorized! Most likely due to corrupt input signalling. 50047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi The rescue strategy is to append it to the front channels (=> ignore index). 50147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi This could cause strange behaviour so return an error to signal it. */ 50247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi err = PCMDMX_INVALID_MODE; 50347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi grpIdx = CH_GROUP_FRONT; 50447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chGrpIdx = numChannels + numChToPlace; 50547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numChToPlace += 1; 50647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (numChInGrp[grpIdx] < PCM_DMX_MAX_CHANNELS_PER_GROUP) { 5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Sort channels by index */ 5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project while ( (i < numChInGrp[grpIdx]) && (chGrpIdx > channelIndices[chIdx[grpIdx][i]]) ) { 5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project i += 1; 5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (j = numChInGrp[grpIdx]; j > i; j -= 1) { 5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chIdx[grpIdx][j] = chIdx[grpIdx][j-1]; 5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chIdx[grpIdx][i] = ch; 5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numChInGrp[grpIdx] += 1; 5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 52247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNEL_GROUPS > 1) 52347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT( (numChInGrp[CH_GROUP_FRONT]+numChInGrp[CH_GROUP_SIDE] 52447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi +numChInGrp[CH_GROUP_REAR]+numChInGrp[CH_GROUP_LFE]) == numChannels); 52547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#else 52647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT( numChInGrp[CH_GROUP_FRONT] == numChannels ); 52747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 52847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 52947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Compose channel offset table: 53047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * Map all channels to the internal representation. */ 53147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numChToPlace = 0; 5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Non-symmetric channels */ 5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (numChInGrp[CH_GROUP_FRONT] & 0x1) { 5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Odd number of front channels -> we have a center channel. 5362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project In MPEG-4 the center has the index 0. */ 5376ab36997af5d5acda4f21d33031f4e45c85f96b7Jean-Michel Trivi offsetTable[CENTER_FRONT_CHANNEL] = chIdx[CH_GROUP_FRONT][0]; 53847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numChFree[CH_GROUP_FRONT] -= 1; 5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (grpIdx = 0; grpIdx < PCM_DMX_MAX_CHANNEL_GROUPS; grpIdx += 1) { 54247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int chMapPos = 0; 54347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ch = 0; /* Index of channel within the specific group */ 5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (grpIdx) { 5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_FRONT: 5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos = LEFT_FRONT_CHANNEL; 5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ch = numChInGrp[grpIdx] & 0x1; 5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 55047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNEL_GROUPS > 1) 5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_SIDE: 5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_REAR: 5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos = LEFT_REAR_CHANNEL; 5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_LFE: 5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos = LOW_FREQUENCY_CHANNEL; 5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 55947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 56147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(0); 5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 56547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Map all channels of the group */ 5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for ( ; ch < numChInGrp[grpIdx]; ch += 1) { 56747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numChFree[grpIdx] > 0) { 5686ab36997af5d5acda4f21d33031f4e45c85f96b7Jean-Michel Trivi offsetTable[chMapPos] = chIdx[grpIdx][ch]; 5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos += 1; 57047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numChFree[grpIdx] -= 1; 5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 57247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Add to the list of hardship cases considering a MPEG-like sorting order: */ 57347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int pos, sortIdx = grpIdx*PCM_DMX_MAX_CHANNELS_PER_GROUP + channelIndices[chIdx[grpIdx][ch]]; 57447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (pos = numChToPlace; pos > 0; pos -= 1) { 57547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (h2pSortIdx[pos-1] > sortIdx) { 57647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi hardToPlace[pos] = hardToPlace[pos-1]; 57747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi h2pSortIdx[pos] = h2pSortIdx[pos-1]; 57847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 57947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Insert channel at the current index/position */ 58047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 58147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 58247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 58347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi hardToPlace[pos] = chIdx[grpIdx][ch]; 58447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi h2pSortIdx[pos] = sortIdx; 58547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numChToPlace += 1; 5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 59047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Assign the hardship cases */ 59147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int chMapPos = 0; 59247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int mappingHeat = 0; 59347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = 0; ch < numChToPlace; ch+=1) { 59447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int chAssigned = 0; 59547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 59647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Just assigning the channels to the next best slot can lead to undesired results (especially for x/x/1.x 59747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi configurations). Thus use the MPEG-like sorting index to find the best fitting slot for each channel. 59847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi If this is not possible the sorting index will be ignored (mappingHeat >= 2). */ 59947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for ( ; chMapPos < PCM_DMX_MAX_CHANNELS; chMapPos+=1) { 60047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (offsetTable[chMapPos] == 255) { 60147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int prvSortIdx = 0; 60247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int nxtSortIdx = (CH_GROUP_LFE+1)*PCM_DMX_MAX_CHANNELS_PER_GROUP; 60347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 60447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (mappingHeat < 2) { 60547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (chMapPos < LEFT_REAR_CHANNEL) { 60647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Got front channel slot */ 60747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi prvSortIdx = CH_GROUP_FRONT*PCM_DMX_MAX_CHANNELS_PER_GROUP + chMapPos - CENTER_FRONT_CHANNEL; 60847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi nxtSortIdx = CH_GROUP_SIDE *PCM_DMX_MAX_CHANNELS_PER_GROUP; 60947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 61047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else if (chMapPos < LOW_FREQUENCY_CHANNEL) { 61147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Got back channel slot */ 61247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi prvSortIdx = CH_GROUP_REAR*PCM_DMX_MAX_CHANNELS_PER_GROUP + chMapPos - LEFT_REAR_CHANNEL; 61347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi nxtSortIdx = CH_GROUP_LFE *PCM_DMX_MAX_CHANNELS_PER_GROUP; 61447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 61547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else if (chMapPos < LEFT_MULTIPRPS_CHANNEL) { 61647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Got lfe channel slot */ 61747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi prvSortIdx = CH_GROUP_LFE *PCM_DMX_MAX_CHANNELS_PER_GROUP + chMapPos - LOW_FREQUENCY_CHANNEL; 61847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi nxtSortIdx = (CH_GROUP_LFE+1)*PCM_DMX_MAX_CHANNELS_PER_GROUP; 61947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 62047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 62147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 62247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Assign the channel only if its sort index is within the range */ 62347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (h2pSortIdx[ch] >= prvSortIdx) 62447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (h2pSortIdx[ch] < nxtSortIdx) ) { 62547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi offsetTable[chMapPos++] = hardToPlace[ch]; 62647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chAssigned = 1; 62747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 62847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 62947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 63047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 63147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (chAssigned == 0) { 63247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chMapPos = 0; 63347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ch -= 1; 63447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mappingHeat += 1; 63547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi continue; 63647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 63747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 64047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Compose the channel mode */ 64147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *chMode = (PCM_DMX_CHANNEL_MODE)( (numChInGrp[CH_GROUP_FRONT] & 0xF) 64247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNEL_GROUPS > 1) 64347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi | (numChInGrp[CH_GROUP_SIDE] & 0xF) << 4 64447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi | (numChInGrp[CH_GROUP_REAR] & 0xF) << 8 64547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi | (numChInGrp[CH_GROUP_LFE] & 0xF) << 12 64647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 64747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ); 64847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 64947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return err; 6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Generate a channel offset table and complete channel description for a given (packed) channel mode. 65447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * This function is the inverse to the getChannelMode() routine but does not support weird channel 65547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * configurations. All channels have to be in the normal height layer and there must not be more 65647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * channels in each group than given by maxChInGrp. 65747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] The packed channel mode of the configuration to be processed. 6582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Array containing the channel mapping to be used (From MPEG PCE ordering to whatever is required). 6592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [out] Array where corresponding channel types for each channels are stored into. 6602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [out] Array where corresponding channel type indices for each output channel are stored into. 6612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [out] Array where the buffer offsets for each channel are stored into. 6622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns None. 6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 66447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic 6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid getChannelDescription ( 6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const PCM_DMX_CHANNEL_MODE chMode, /* in */ 66747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const UCHAR channelMapping[][8], /* in */ 6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project AUDIO_CHANNEL_TYPE channelType[], /* out */ 6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR channelIndices[], /* out */ 6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR offsetTable[PCM_DMX_MAX_CHANNELS] /* out */ 6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const UCHAR *pChannelMap; 6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int grpIdx, ch = 0, numChannels = 0; 6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR numChInGrp[PCM_DMX_MAX_CHANNEL_GROUPS]; 6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(channelType != NULL); 6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(channelIndices != NULL); 6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(channelMapping != NULL); 6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(offsetTable != NULL); 6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Init output arrays */ 68347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemclear(channelType, PCM_DMX_MAX_IO_CHANNELS*sizeof(AUDIO_CHANNEL_TYPE)); 68447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemclear(channelIndices, PCM_DMX_MAX_IO_CHANNELS*sizeof(UCHAR)); 6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemset(offsetTable, 255, PCM_DMX_MAX_CHANNELS*sizeof(UCHAR)); 6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Extract the number of channels per group */ 6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numChInGrp[CH_GROUP_FRONT] = chMode & 0xF; 68947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNEL_GROUPS > 1) 6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numChInGrp[CH_GROUP_SIDE] = (chMode >> 4) & 0xF; 6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numChInGrp[CH_GROUP_REAR] = (chMode >> 8) & 0xF; 6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numChInGrp[CH_GROUP_LFE] = (chMode >> 12) & 0xF; 69347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Summerize to get the total number of channels */ 6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (grpIdx = 0; grpIdx < PCM_DMX_MAX_CHANNEL_GROUPS; grpIdx += 1) { 6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numChannels += numChInGrp[grpIdx]; 6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Get the appropriate channel map */ 70147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (chMode) { 70247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_1_0_0_0: 70347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_2_0_0_0: 70447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_0_0: 70547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_1_0: 70647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_2_0: 70747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_2_1: 70847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pChannelMap = channelMapping[numChannels]; 70947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 71047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_3_1: 71147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pChannelMap = channelMapping[11]; 71247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 71347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_4_1: 71447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pChannelMap = channelMapping[12]; 71547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 71647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_5_0_2_1: 71747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pChannelMap = channelMapping[7]; 71847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 71947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 72047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* fallback */ 72147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pChannelMap = channelMapping[0]; 72247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 72347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Compose channel offset table */ 7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Non-symmetric channels */ 7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (numChInGrp[CH_GROUP_FRONT] & 0x1) { 7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Odd number of front channels -> we have a center channel. 7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project In MPEG-4 the center has the index 0. */ 73147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int mappedIdx = pChannelMap[ch]; 73247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi offsetTable[CENTER_FRONT_CHANNEL] = mappedIdx; 73347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelType[mappedIdx] = ACT_FRONT; 73447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelIndices[mappedIdx] = 0; 7352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ch += 1; 7362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (grpIdx = 0; grpIdx < PCM_DMX_MAX_CHANNEL_GROUPS; grpIdx += 1) { 73947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi AUDIO_CHANNEL_TYPE type = ACT_NONE; 74047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int chMapPos = 0, maxChannels = 0; 74147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int chIdx = 0; /* Index of channel within the specific group */ 7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (grpIdx) { 7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_FRONT: 7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project type = ACT_FRONT; 7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos = LEFT_FRONT_CHANNEL; 7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxChannels = 3; 7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chIdx = numChInGrp[grpIdx] & 0x1; 7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 75047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNEL_GROUPS > 1) 7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_SIDE: 75247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Always map side channels to the multipurpose group. */ 7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project type = ACT_SIDE; 75447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chMapPos = LEFT_MULTIPRPS_CHANNEL; 7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_REAR: 7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project type = ACT_BACK; 7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos = LEFT_REAR_CHANNEL; 7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxChannels = 2; 7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH_GROUP_LFE: 7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project type = ACT_LFE; 7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos = LOW_FREQUENCY_CHANNEL; 7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxChannels = 1; 7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 76647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 77147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Map all channels in this group */ 77247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for ( ; chIdx < numChInGrp[grpIdx]; chIdx += 1) { 77347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int mappedIdx = pChannelMap[ch]; 77447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (chIdx == maxChannels) { 77547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* No space left in this channel group! 77647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Use the multipurpose group instead: */ 77747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chMapPos = LEFT_MULTIPRPS_CHANNEL; 77847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 77947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi offsetTable[chMapPos] = mappedIdx; 78047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelType[mappedIdx] = type; 78147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelIndices[mappedIdx] = chIdx; 7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project chMapPos += 1; 7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ch += 1; 7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 78847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/** Private helper function for downmix matrix manipulation that initializes 78947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * one row in a given downmix matrix (corresponding to one output channel). 79047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to fixed-point parts of the downmix matrix. 79147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to scale factor matrix associated to the downmix factors. 79247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Index of channel (row) to be initialized. 79347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @returns Nothing to return. 79447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi **/ 79547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic 79647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivivoid dmxInitChannel( 79747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX mixFactors[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 79847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT mixScales[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 79947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const unsigned int outCh 80047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ) 80147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 80247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi unsigned int inCh; 80347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < PCM_DMX_MAX_CHANNELS; inCh+=1) { 80447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (inCh == outCh) { 80547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[outCh][inCh] = FL2FXCONST_DMX(0.5f); 80647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixScales[outCh][inCh] = 1; 80747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 80847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[outCh][inCh] = FL2FXCONST_DMX(0.0f); 80947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixScales[outCh][inCh] = 0; 81047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 81147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 81247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} 81347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 81447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/** Private helper function for downmix matrix manipulation that does a reset 81547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * of one row in a given downmix matrix (corresponding to one output channel). 81647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to fixed-point parts of the downmix matrix. 81747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to scale factor matrix associated to the downmix factors. 81847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Index of channel (row) to be cleared/reset. 81947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @returns Nothing to return. 82047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi **/ 82147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic 82247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivivoid dmxClearChannel( 82347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX mixFactors[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 82447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT mixScales[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 82547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const unsigned int outCh 82647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ) 82747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 82847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemclear(&mixFactors[outCh], PCM_DMX_MAX_CHANNELS*sizeof(FIXP_DMX)); 82947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemclear(&mixScales[outCh], PCM_DMX_MAX_CHANNELS*sizeof(INT)); 83047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} 83147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 83247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/** Private helper function for downmix matrix manipulation that applies a source channel (row) 83347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * scaled by a given mix factor to a destination channel (row) in a given downmix matrix. 83447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * Existing mix factors of the destination channel (row) will get overwritten. 83547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to fixed-point parts of the downmix matrix. 83647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to scale factor matrix associated to the downmix factors. 83747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Index of source channel (row). 83847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Index of destination channel (row). 83947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Fixed-point part of mix factor to be applied. 84047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Scale factor of mix factor to be applied. 84147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @returns Nothing to return. 84247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi **/ 84347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic 84447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivivoid dmxSetChannel( 84547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX mixFactors[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 84647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT mixScales[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 84747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const unsigned int dstCh, 84847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const unsigned int srcCh, 84947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const FIXP_DMX factor, 85047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const INT scale 85147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ) 85247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 85347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int ch; 85447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch=0; ch < PCM_DMX_MAX_CHANNELS; ch+=1) { 85547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (mixFactors[srcCh][ch] != (FIXP_DMX)0) { 85647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[dstCh][ch] = FX_DBL2FX_DMX(fMult(mixFactors[srcCh][ch], factor)); 85747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixScales[dstCh][ch] = mixScales[srcCh][ch] + scale; 85847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 85947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 86047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} 86147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 86247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/** Private helper function for downmix matrix manipulation that adds a source channel (row) 86347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * scaled by a given mix factor to a destination channel (row) in a given downmix matrix. 86447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to fixed-point parts of the downmix matrix. 86547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to scale factor matrix associated to the downmix factors. 86647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Index of source channel (row). 86747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Index of destination channel (row). 86847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Fixed-point part of mix factor to be applied. 86947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Scale factor of mix factor to be applied. 87047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @returns Nothing to return. 87147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi **/ 87247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic 87347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivivoid dmxAddChannel( 87447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX mixFactors[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 87547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT mixScales[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 87647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const unsigned int dstCh, 87747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const unsigned int srcCh, 87847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const FIXP_DMX factor, 87947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const INT scale 88047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ) 88147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 88247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int ch; 88347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch=0; ch < PCM_DMX_MAX_CHANNELS; ch+=1) { 88447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DBL addFact = fMult(mixFactors[srcCh][ch], factor); 88547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (addFact != (FIXP_DMX)0) { 88647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT newScale = mixScales[srcCh][ch] + scale; 88747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (mixFactors[dstCh][ch] != (FIXP_DMX)0) { 88847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (newScale > mixScales[dstCh][ch]) { 88947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[dstCh][ch] >>= newScale - mixScales[dstCh][ch]; 89047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 89147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi addFact >>= mixScales[dstCh][ch] - newScale; 89247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi newScale = mixScales[dstCh][ch]; 89347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 89447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 89547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[dstCh][ch] += FX_DBL2FX_DMX(addFact); 89647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixScales[dstCh][ch] = newScale; 89747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 89847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 89947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} 90047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 90147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 90247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/** Private function that creates a downmix factor matrix depending on the input and output 90347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * configuration, the user parameters as well as the given metadata. This function is the modules 90447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * brain and hold all downmix algorithms. 90547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Flag that indicates if inChMode holds a real (packed) channel mode or has been 90647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi converted to a MPEG-4 channel configuration index. 90747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Dependent on the inModeIsCfg flag this field hands in a (packed) channel mode or 90847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi the corresponding MPEG-4 channel configuration index.of the input configuration. 90947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] The (packed) channel mode of the output configuration. 91047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Pointer to structure holding all current user parameter. 91147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Pointer to field holding all current meta data. 91247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [out] Pointer to fixed-point parts of the downmix matrix. Normalized to one scale factor. 91347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [out] The common scale factor of the downmix matrix. 91447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @returns An error code. 91547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi **/ 91647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic 91747c680c62246594107da0a8995c953dfb8040bceJean-Michel TriviPCMDMX_ERROR getMixFactors ( 91847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const UCHAR inModeIsCfg, 91947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_CHANNEL_MODE inChMode, 92047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const PCM_DMX_CHANNEL_MODE outChMode, 92147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const PCM_DMX_USER_PARAMS *pParams, 92247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const DMX_BS_META_DATA *pMetaData, 92347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX mixFactors[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS], 92447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT *pOutScale 92547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ) 92647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 92747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCMDMX_ERROR err = PCMDMX_OK; 92847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT mixScales[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS]; 92947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT maxScale = 0; 93047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int numInChannel, numOutChannel; 93147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi unsigned int outCh, inCh, inChCfg = 0; 93247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi unsigned int valid[PCM_DMX_MAX_CHANNELS] = { 0 }; 93347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 93447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(pMetaData != NULL); 93547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(mixFactors != NULL); 93647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Check on a supported output configuration */ 93747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT( (outChMode == CH_MODE_1_0_0_0) 93847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (outChMode == CH_MODE_2_0_0_0) 93947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (outChMode == CH_MODE_3_0_2_1) ); 94047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 94147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (inModeIsCfg) { 94247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Workaround for the ambiguity of the internal channel modes. 94347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Convert channel config to channel mode: */ 94447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChCfg = (unsigned int)inChMode; 94547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (inChCfg) { 94647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case 1: case 2: case 3: 94747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_CHANNELS > 3) 94847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case 4: case 5: case 6: 94947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 95047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChMode = outChModeTable[inChCfg]; 95147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 95247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case 11: 95347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChMode = CH_MODE_3_0_3_1; 95447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 95547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case 12: 95647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChMode = CH_MODE_3_0_4_1; 95747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 95847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case 7: case 14: 95947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChMode = CH_MODE_5_0_2_1; 96047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 96147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 96247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(0); 96347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 96447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 96547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 96647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Extract the total number of input channels */ 96747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numInChannel = (inChMode&0xF) 96847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi + ((inChMode>> 4)&0xF) 96947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi + ((inChMode>> 8)&0xF) 97047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi + ((inChMode>>12)&0xF); 97147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Extract the total number of output channels */ 97247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numOutChannel = (outChMode&0xF) 97347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi + ((outChMode>> 4)&0xF) 97447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi + ((outChMode>> 8)&0xF) 97547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi + ((outChMode>>12)&0xF); 97647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 97747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* MPEG ammendment 4 aka ETSI metadata and fallback mode: */ 97847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 97947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 98047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Create identity DMX matrix: */ 98147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < PCM_DMX_MAX_CHANNELS; outCh+=1) { 98247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxInitChannel( mixFactors, mixScales, outCh ); 98347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 98447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (((inChMode>>12)&0xF) == 0) { 98547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Clear empty or wrongly mapped input channel */ 98647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxClearChannel( mixFactors, mixScales, LOW_FREQUENCY_CHANNEL ); 98747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 98847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 98947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* FIRST STAGE: */ 99047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numInChannel > SIX_CHANNEL) 99147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Always use MPEG equations either with meta data or with default values. */ 99247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX dMixFactA, dMixFactB; 99347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT dMixScaleA, dMixScaleB; 99447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int isValidCfg = TRUE; 99547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 99647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Get factors from meta data */ 99747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dMixFactA = abMixLvlValueTab[pMetaData->dmixIdxA]; 99847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dMixScaleA = (pMetaData->dmixIdxA==0) ? 1 : 0; 99947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dMixFactB = abMixLvlValueTab[pMetaData->dmixIdxB]; 100047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dMixScaleB = (pMetaData->dmixIdxB==0) ? 1 : 0; 100147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 100247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Check if input is in the list of supported configurations */ 100347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (inChMode) { 100447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_3_1: /* chCfg 11 */ 100547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 6.1ch: C' = C; L' = L; R' = R; LFE' = LFE; 100647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Ls' = Ls*dmix_a_idx + Cs*dmix_b_idx; 100747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Rs' = Rs*dmix_a_idx + Cs*dmix_b_idx; */ 100847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxClearChannel( mixFactors, mixScales, RIGHT_MULTIPRPS_CHANNEL ); /* clear empty input channel */ 100947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_REAR_CHANNEL, dMixFactA, dMixScaleA ); 101047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB ); 101147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, RIGHT_REAR_CHANNEL, dMixFactA, dMixScaleA ); 101247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB ); 101347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 101447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_2_1_0: 101547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_2_1_1: /* chCfg 11 but with side channels */ 101647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 6.1ch: C' = C; L' = L; R' = R; LFE' = LFE; 101747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Ls' = Ls*dmix_a_idx + Cs*dmix_b_idx; 101847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Rs' = Rs*dmix_a_idx + Cs*dmix_b_idx; */ 101947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxClearChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL ); /* clear empty input channel */ 102047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, LEFT_REAR_CHANNEL, dMixFactB, dMixScaleB ); 102147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, RIGHT_MULTIPRPS_CHANNEL, dMixFactA, dMixScaleA ); 102247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_REAR_CHANNEL, dMixFactB, dMixScaleB ); 102347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_MULTIPRPS_CHANNEL, dMixFactA, dMixScaleA ); 102447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi isValidCfg = FALSE; 102547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi err = PCMDMX_INVALID_MODE; 102647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 102747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_5_2_1_0: 102847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_5_0_1_0: 102947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_5_0_1_1: 103047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Ls' = Cs*dmix_a_idx; 103147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Rs' = Cs*dmix_a_idx; */ 103247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxClearChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL ); /* clear empty input channel */ 103347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, LEFT_REAR_CHANNEL, dMixFactA, dMixScaleA ); 103447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_REAR_CHANNEL, dMixFactA, dMixScaleA ); 103547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi isValidCfg = FALSE; 103647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi err = PCMDMX_INVALID_MODE; 103747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 103847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_4_1: /* chCfg 12 */ 103947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 7.1ch Surround Back: C' = C; L' = L; R' = R; LFE' = LFE; 104047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Ls' = Ls*dmix_a_idx + Lsr*dmix_b_idx; 104147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Rs' = Rs*dmix_a_idx + Rsr*dmix_b_idx; */ 104247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_REAR_CHANNEL, dMixFactA, dMixScaleA ); 104347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB ); 104447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, RIGHT_REAR_CHANNEL, dMixFactA, dMixScaleA ); 104547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, RIGHT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB ); 104647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 104747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_5_0_2_1: /* chCfg 7 || 14 */ 104847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (inChCfg == 14) { 104947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 7.1ch Front Height: C' = C; Ls' = Ls; Rs' = Rs; LFE' = LFE; 105047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi L' = L*dmix_a_idx + Lv*dmix_b_idx; 105147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = R*dmix_a_idx + Rv*dmix_b_idx; */ 105247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, dMixFactA, dMixScaleA ); 105347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB ); 105447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, dMixFactA, dMixScaleA ); 105547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_MULTIPRPS_CHANNEL, dMixFactB, dMixScaleB ); 105647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 105747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 7.1ch Front: Ls' = Ls; Rs' = Rs; LFE' = LFE; 105847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi C' = C + (Lc+Rc)*dmix_a_idx; 105947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi L' = L + Lc*dmix_b_idx; 106047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = R + Rc*dmix_b_idx; 106147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi CAUTION: L+R are not at (MPEG) index 1+2. */ 106247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, CENTER_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, dMixFactA, dMixScaleA ); 106347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, CENTER_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, dMixFactA, dMixScaleA ); 106447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, dMixFactB, dMixScaleB ); 106547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_MULTIPRPS_CHANNEL, FL2FXCONST_DMX(0.5f), 1 ); 106647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, dMixFactB, dMixScaleB ); 106747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_MULTIPRPS_CHANNEL, FL2FXCONST_DMX(0.5f), 1 ); 106847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 106947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 107047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 107147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Nothing to do. Just use the identity matrix. */ 107247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi isValidCfg = FALSE; 107347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi err = PCMDMX_INVALID_MODE; 107447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 107547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 107647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 107747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Add additional DMX gain */ 107847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (isValidCfg == TRUE) 107947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (pMetaData->dmxGainIdx5 != 0)) 108047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Apply DMX gain 5 */ 108147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX dmxGain; 108247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT dmxScale; 108347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT sign = (pMetaData->dmxGainIdx5 & 0x40) ? -1 : 1; 108447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT val = pMetaData->dmxGainIdx5 & 0x3F; 108547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 108647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 10^(dmx_gain_5/80) */ 108747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxGain = FX_DBL2FX_DMX( fLdPow( 108847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DBL(0.830482023721841f), 2, /* log2(10) */ 108947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi (FIXP_DBL)(sign*val*(LONG)FL2FXCONST_DBL(0.0125f)), 0, 109047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi &dmxScale ) 109147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ); 109247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Currently only positive scale factors supported! */ 109347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (dmxScale < 0) { 109447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxGain >>= -dmxScale; 109547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxScale = 0; 109647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 109747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 109847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, CENTER_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, dmxGain, dmxScale ); 109947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, dmxGain, dmxScale ); 110047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, dmxGain, dmxScale ); 110147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_REAR_CHANNEL, LEFT_REAR_CHANNEL, dmxGain, dmxScale ); 110247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_REAR_CHANNEL, RIGHT_REAR_CHANNEL, dmxGain, dmxScale ); 110347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LOW_FREQUENCY_CHANNEL, LOW_FREQUENCY_CHANNEL, dmxGain, dmxScale ); 110447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 110547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 110647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Mark the output channels */ 110747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[CENTER_FRONT_CHANNEL] = 1; 110847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[LEFT_FRONT_CHANNEL] = 1; 110947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[RIGHT_FRONT_CHANNEL] = 1; 111047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[LEFT_REAR_CHANNEL] = 1; 111147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[RIGHT_REAR_CHANNEL] = 1; 111247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[LOW_FREQUENCY_CHANNEL] = 1; 111347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 111447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Update channel mode for the next stage */ 111547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChMode = CH_MODE_3_0_2_1; 111647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 111747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 111847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* SECOND STAGE: */ 111947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numOutChannel <= TWO_CHANNEL) { 112047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Create DMX matrix according to input configuration */ 112147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (inChMode) { 112247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_2_0_0_0: /* chCfg 2 */ 112347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Apply the dual channel mode. */ 112447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (pParams->dualChannelMode) { 112547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH1_MODE: /* L' = 0.707 * Ch1; 112647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = 0.707 * Ch1; */ 112747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 112847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 112947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 113047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH2_MODE: /* L' = 0.707 * Ch2; 113147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = 0.707 * Ch2; */ 113247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 113347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 113447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 113547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case MIXED_MODE: /* L' = 0.5*Ch1 + 0.5*Ch2; 113647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = 0.5*Ch1 + 0.5*Ch2; */ 113747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0 ); 113847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0 ); 113947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0 ); 114047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, FL2FXCONST_DMX(0.5f), 0 ); 114147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 114247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 114347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case STEREO_MODE: 114447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Nothing to do */ 114547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 114647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 114747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 114847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_2_0_1_0: 114947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* L' = L + 0.707*S; 115047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = R + 0.707*S; */ 115147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 115247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 115347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 115447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_0_0: /* chCfg 3 */ 115547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* L' = L + 0.707*C; 115647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = R + 0.707*C; */ 115747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 115847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 115947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 116047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_1_0: /* chCfg 4 */ 116147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* L' = L + 0.707*C + 0.707*S; 116247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = R + 0.707*C + 0.707*S; */ 116347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 116447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 116547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 116647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, FL2FXCONST_DMX(0.707f), 0 ); 116747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 116847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_2_0: /* chCfg 5 */ 116947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_2_1: /* chCfg 6 */ 117047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* MPEG + ITU + DLB 117147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi But because the default downmix equations and coefficients are equal we stick to MPEG. */ 117247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (pMetaData->typeFlags & TYPE_DSE_DATA) 117347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || !(pMetaData->typeFlags & TYPE_PCE_DATA) ) 117447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { 117547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX cMixLvl, sMixLvl, lMixLvl; 117647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT cMixScale, sMixScale, lMixScale; 117747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 117847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Get factors from meta data */ 117947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi cMixLvl = abMixLvlValueTab[pMetaData->cLevIdx]; 118047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi cMixScale = (pMetaData->cLevIdx==0) ? 1 : 0; 118147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi sMixLvl = abMixLvlValueTab[pMetaData->sLevIdx]; 118247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi sMixScale = (pMetaData->sLevIdx==0) ? 1 : 0; 118347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi lMixLvl = lfeMixLvlValueTab[pMetaData->dmixIdxLfe]; 118447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (pMetaData->dmixIdxLfe <= 1) { 118547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi lMixScale = 2; 118647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else if (pMetaData->dmixIdxLfe <= 5) { 118747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi lMixScale = 1; 118847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 118947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi lMixScale = 0; 119047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 119147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Setup the DMX matrix */ 119247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (pParams->pseudoSurrMode == FORCE_PS_DMX) 119347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || ((pParams->pseudoSurrMode == AUTO_PS_DMX) && (pMetaData->pseudoSurround==1))) 119447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* L' = L + C*clev - (Ls+Rs)*slev + LFE*lflev; 119547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = R + C*clev + (Ls+Rs)*slev + LFE*lflev; */ 119647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, cMixLvl, cMixScale ); 119747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, -sMixLvl, sMixScale ); 119847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, RIGHT_REAR_CHANNEL, -sMixLvl, sMixScale ); 119947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale ); 120047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, cMixLvl, cMixScale ); 120147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, sMixLvl, sMixScale ); 120247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_REAR_CHANNEL, sMixLvl, sMixScale ); 120347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale ); 120447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 120547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else 120647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* L' = L + C*clev + Ls*slev + LFE*llev; 120747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = R + C*clev + Rs*slev + LFE*llev; */ 120847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, cMixLvl, cMixScale ); 120947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, sMixLvl, sMixScale ); 121047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale ); 121147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, cMixLvl, cMixScale ); 121247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_REAR_CHANNEL, sMixLvl, sMixScale ); 121347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LOW_FREQUENCY_CHANNEL, lMixLvl, lMixScale ); 121447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 121547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 121647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Add additional DMX gain */ 121747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( pMetaData->dmxGainIdx2 != 0 ) 121847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Apply DMX gain 2 */ 121947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX dmxGain; 122047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT dmxScale; 122147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT sign = (pMetaData->dmxGainIdx2 & 0x40) ? -1 : 1; 122247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT val = pMetaData->dmxGainIdx2 & 0x3F; 122347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 122447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 10^(dmx_gain_2/80) */ 122547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxGain = FX_DBL2FX_DMX( fLdPow( 122647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FL2FXCONST_DBL(0.830482023721841f), 2, /* log2(10) */ 122747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi (FIXP_DBL)(sign*val*(LONG)FL2FXCONST_DBL(0.0125f)), 0, 122847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi &dmxScale ) 122947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ); 123047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Currently only positive scale factors supported! */ 123147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (dmxScale < 0) { 123247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxGain >>= -dmxScale; 123347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxScale = 0; 123447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 123547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 123647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, dmxGain, dmxScale ); 123747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, dmxGain, dmxScale ); 123847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 123947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 124047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCE_METADATA_ENABLE 124147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else { 124247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX flev, clev, slevLL, slevLR, slevRL, slevRR; 124347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX mtrxMixDwnCoef = mpegMixDownIdx2Coef[pMetaData->matrixMixdownIdx]; 124447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 124547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (pParams->pseudoSurrMode == FORCE_PS_DMX) 124647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || ((pParams->pseudoSurrMode == AUTO_PS_DMX) && (pMetaData->pseudoSurround==1))) 124747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* 3/2 input: L' = (1.707+2*A)^-1 * [L+0.707*C-A*Ls-A*Rs]; 124847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = (1.707+2*A)^-1 * [R+0.707*C+A*Ls+A*Rs]; */ 124947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi flev = mpegMixDownIdx2PreFact[1][pMetaData->matrixMixdownIdx]; 125047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi slevRR = slevRL = FX_DBL2FX_DMX(fMult(flev, mtrxMixDwnCoef)); 125147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi slevLL = slevLR = -slevRL; 125247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 125347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else { 125447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 3/2 input: L' = (1.707+A)^-1 * [L+0.707*C+A*Ls]; 125547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi R' = (1.707+A)^-1 * [R+0.707*C+A*Rs]; */ 125647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi flev = mpegMixDownIdx2PreFact[0][pMetaData->matrixMixdownIdx]; 125747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi slevRR = slevLL = FX_DBL2FX_DMX(fMult(flev, mtrxMixDwnCoef)); 125847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi slevLR = slevRL = (FIXP_SGL)0; 125947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 126047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* common factor */ 126147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi clev = FX_DBL2FX_DMX(fMult(flev, mpegMixDownIdx2Coef[0] /* 0.707 */)); 126247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 126347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, flev, 0 ); 126447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, clev, 0 ); 126547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, slevLL, 0 ); 126647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, LEFT_FRONT_CHANNEL, RIGHT_REAR_CHANNEL, slevLR, 0 ); 126747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 126847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, flev, 0 ); 126947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, CENTER_FRONT_CHANNEL, clev, 0 ); 127047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, LEFT_REAR_CHANNEL, slevRL, 0 ); 127147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, RIGHT_FRONT_CHANNEL, RIGHT_REAR_CHANNEL, slevRR, 0 ); 127247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 127347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* PCE_METADATA_ENABLE */ 127447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 127547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 127647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* This configuration does not fit to any known downmix equation! */ 127747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi err = PCMDMX_INVALID_MODE; 127847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 127947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 128047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Mark the output channels */ 128147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemclear(valid, PCM_DMX_MAX_CHANNELS*sizeof(unsigned int)); 128247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[LEFT_FRONT_CHANNEL] = 1; 128347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[RIGHT_FRONT_CHANNEL] = 1; 128447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Update channel mode for the next stage */ 128547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChMode = CH_MODE_2_0_0_0; 128647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 128747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 128847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numOutChannel == ONE_CHANNEL) { 128947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX monoMixLevel; 129047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT monoMixScale; 129147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 129247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCE_METADATA_ENABLE 129347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (pMetaData->typeFlags & TYPE_PCE_DATA) 129447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && !(pMetaData->typeFlags & TYPE_DSE_DATA) ) 129547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* C' = (3+2*A)^-1 * [C+L+R+A*Ls+A+Rs]; */ 129647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi monoMixLevel = mpegMixDownIdx2PreFact[2][pMetaData->matrixMixdownIdx]; 129747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi monoMixScale = 0; 129847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 129947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxClearChannel( mixFactors, mixScales, CENTER_FRONT_CHANNEL ); 130047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[CENTER_FRONT_CHANNEL][CENTER_FRONT_CHANNEL] = monoMixLevel; 130147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[CENTER_FRONT_CHANNEL][LEFT_FRONT_CHANNEL] = monoMixLevel; 130247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[CENTER_FRONT_CHANNEL][RIGHT_FRONT_CHANNEL] = monoMixLevel; 130347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi monoMixLevel = FX_DBL2FX_DMX(fMult(monoMixLevel, mpegMixDownIdx2Coef[pMetaData->matrixMixdownIdx])); 130447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[CENTER_FRONT_CHANNEL][LEFT_REAR_CHANNEL] = monoMixLevel; 130547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[CENTER_FRONT_CHANNEL][RIGHT_REAR_CHANNEL] = monoMixLevel; 130647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 130747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else 130847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 130947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* C' = L + R; [default] */ 131047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi monoMixLevel = FL2FXCONST_DMX(0.5f); 131147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi monoMixScale = 1; 131247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxClearChannel( mixFactors, mixScales, CENTER_FRONT_CHANNEL ); /* C is not in the mix */ 131347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxSetChannel( mixFactors, mixScales, CENTER_FRONT_CHANNEL, LEFT_FRONT_CHANNEL, monoMixLevel, monoMixScale ); 131447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxAddChannel( mixFactors, mixScales, CENTER_FRONT_CHANNEL, RIGHT_FRONT_CHANNEL, monoMixLevel, monoMixScale ); 131547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 131647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 131747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Mark the output channel */ 131847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemclear(valid, PCM_DMX_MAX_CHANNELS*sizeof(unsigned int)); 131947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi valid[CENTER_FRONT_CHANNEL] = 1; 132047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 132147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 132247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define MAX_SEARCH_START_VAL ( -7 ) 132347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 132447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { 132547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi LONG chSum[PCM_DMX_MAX_CHANNELS]; 132647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT chSumMax = MAX_SEARCH_START_VAL; 132747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 132847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Determine the current maximum scale factor */ 132947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < PCM_DMX_MAX_CHANNELS; outCh+=1) { 133047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (valid[outCh]!=0) { 133147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < PCM_DMX_MAX_CHANNELS; inCh+=1) { 133247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (mixScales[outCh][inCh] > maxScale) 133347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Store the new maximum */ 133447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi maxScale = mixScales[outCh][inCh]; 133547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 133647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 133747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 133847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 133947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 134047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Individualy analyse output chanal levels */ 134147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < PCM_DMX_MAX_CHANNELS; outCh+=1) { 134247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chSum[outCh] = MAX_SEARCH_START_VAL; 134347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (valid[outCh]!=0) { 134447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int ovrflwProtScale = 0; 134547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 134647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Accumulate all factors for each output channel */ 134747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chSum[outCh] = 0; 134847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < PCM_DMX_MAX_CHANNELS; inCh+=1) { 134947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi SHORT addFact = FX_DMX2SHRT(mixFactors[outCh][inCh]); 135047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( mixScales[outCh][inCh] <= maxScale ) { 135147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi addFact >>= maxScale - mixScales[outCh][inCh]; 135247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 135347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi addFact <<= mixScales[outCh][inCh] - maxScale; 135447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 135547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chSum[outCh] += addFact; 135647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 135747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (chSum[outCh] > (LONG)MAXVAL_SGL) { 135847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi while (chSum[outCh] > (LONG)MAXVAL_SGL) { 135947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ovrflwProtScale += 1; 136047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chSum[outCh] >>= 1; 136147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 136247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else if (chSum[outCh] > 0) { 136347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi while ((chSum[outCh]<<1) <= (LONG)MAXVAL_SGL) { 136447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ovrflwProtScale -= 1; 136547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chSum[outCh] <<= 1; 136647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 136747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 136847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Store the differential scaling in the same array */ 136947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chSum[outCh] = ovrflwProtScale; 137047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 137147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 137247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 137347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < PCM_DMX_MAX_CHANNELS; outCh+=1) { 137447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (valid[outCh] != 0) 137547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (chSum[outCh] > chSumMax) ) 137647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Store the new maximum */ 137747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chSumMax = chSum[outCh]; 137847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 137947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 138047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi maxScale = FDKmax(maxScale+chSumMax, 0); 138147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 138247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Normalize all factors */ 138347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < PCM_DMX_MAX_CHANNELS; outCh+=1) { 138447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (valid[outCh]!=0) { 138547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < PCM_DMX_MAX_CHANNELS; inCh+=1) { 138647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (mixFactors[outCh][inCh] != (FIXP_DMX)0) { 138747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( mixScales[outCh][inCh] <= maxScale ) { 138847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[outCh][inCh] >>= maxScale - mixScales[outCh][inCh]; 138947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 139047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[outCh][inCh] <<= mixScales[outCh][inCh] - maxScale; 139147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 139247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixScales[outCh][inCh] = maxScale; 139347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 139447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 139547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 139647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 139747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 139847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 139947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 140047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* return the scale factor */ 140147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pOutScale = maxScale; 140247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 140347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (err); 140447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} 140547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 14062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Open and initialize an instance of the PCM downmix module 14082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [out] Pointer to a buffer receiving the handle of the new instance. 14092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 14102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 14112228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPCMDMX_ERROR pcmDmx_Open ( 14122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX *pSelf 14132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 14142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 14152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX self; 14162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pSelf == NULL) { 14182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_HANDLE); 14192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *pSelf = NULL; 14222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project self = (HANDLE_PCM_DOWNMIX) GetPcmDmxInstance( 0 ); 14242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (self == NULL) { 14252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_OUT_OF_MEMORY); 14262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Reset the full instance */ 14292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pcmDmx_Reset( self, PCMDMX_RESET_FULL ); 14302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *pSelf = self; 14322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_OK); 14342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 14352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Reset all static values like e.g. mixdown coefficients. 14382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Handle of PCM downmix module instance. 14392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Flags telling which parts of the module shall be reset. 14402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 14412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 14422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPCMDMX_ERROR pcmDmx_Reset ( 14432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX self, 14442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UINT flags 14452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 14462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 14472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (self == NULL) { return (PCMDMX_INVALID_HANDLE); } 14482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (flags & PCMDMX_RESET_PARAMS) { 145047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_USER_PARAMS *pParams = &self->userParams; 145147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 145247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParams->dualChannelMode = STEREO_MODE; 145347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParams->pseudoSurrMode = NEVER_DO_PS_DMX; 145447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParams->numOutChannelsMax = PCM_DMX_DFLT_MAX_OUT_CHANNELS; 145547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParams->numOutChannelsMin = PCM_DMX_DFLT_MIN_OUT_CHANNELS; 145647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParams->frameDelay = 0; 145747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParams->expiryFrame = PCM_DMX_DFLT_EXPIRY_FRAME; 145847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 145947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->applyProcessing = 0; 14602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (flags & PCMDMX_RESET_BS_DATA) { 14632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int slot; 146447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Init all slots with a default set */ 14652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (slot = 0; slot <= PCM_DMX_MAX_DELAY_FRAMES; slot += 1) { 146647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(&self->bsMetaData[slot], &dfltMetaData, sizeof(DMX_BS_META_DATA)); 14672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_OK); 14712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 14722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Set one parameter for one instance of the PCM downmix module. 14752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Handle of PCM downmix module instance. 14762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Parameter to be set. 14772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Parameter value. 14782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 14792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 14802228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPCMDMX_ERROR pcmDmx_SetParam ( 14812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX self, 148247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const PCMDMX_PARAM param, 148347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const INT value 14842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 14852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 14862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (param) 14872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 14882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case DMX_BS_DATA_EXPIRY_FRAME: 14892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (self == NULL) 14902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_HANDLE); 149147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.expiryFrame = (value > 0) ? (UINT)value : 0; 14922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 14932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case DMX_BS_DATA_DELAY: 149547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (value > PCM_DMX_MAX_DELAY_FRAMES) 149647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (value < 0) ) { 14972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_UNABLE_TO_SET_PARAM); 14982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (self == NULL) { 15002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_HANDLE); 15012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 150247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.frameDelay = (UCHAR)value; 15032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 15042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 150547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case MIN_NUMBER_OF_OUTPUT_CHANNELS: 150647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (value) { /* supported output channels */ 150747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case -1: case 0: case ONE_CHANNEL: case TWO_CHANNEL: 150847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_OUT_CHANNELS >= 6) 150947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case SIX_CHANNEL: 151047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 151147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_OUT_CHANNELS >= 8) 151247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case EIGHT_CHANNEL: 151347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 15142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 15152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 15162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_UNABLE_TO_SET_PARAM); 15172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (self == NULL) 15192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_HANDLE); 152047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Store the new value */ 152147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.numOutChannelsMin = (value > 0) ? value : -1; 152247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (value > 0) 152347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (self->userParams.numOutChannelsMax > 0) 152447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (value > self->userParams.numOutChannelsMax) ) 152547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* MIN > MAX would be an invalid state. Thus set MAX = MIN in this case. */ 152647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.numOutChannelsMax = self->userParams.numOutChannelsMin; 15272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 15292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 153047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case MAX_NUMBER_OF_OUTPUT_CHANNELS: 153147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (value) { /* supported output channels */ 153247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case -1: case 0: case ONE_CHANNEL: case TWO_CHANNEL: 153347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_OUT_CHANNELS >= 6) 153447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case SIX_CHANNEL: 153547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 153647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_OUT_CHANNELS >= 8) 153747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case EIGHT_CHANNEL: 153847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 153947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 154047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 154147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_UNABLE_TO_SET_PARAM); 154247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 154347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (self == NULL) 154447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_INVALID_HANDLE); 154547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Store the new value */ 154647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.numOutChannelsMax = (value > 0) ? value : -1; 154747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (value > 0) 154847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (value < self->userParams.numOutChannelsMin) ) 154947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* MAX < MIN would be an invalid state. Thus set MIN = MAX in this case. */ 155047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.numOutChannelsMin = self->userParams.numOutChannelsMax; 155147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 155247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 155347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 155447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case DMX_DUAL_CHANNEL_MODE: 15552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch ((DUAL_CHANNEL_MODE)value) { 15562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case STEREO_MODE: 15572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH1_MODE: 15582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH2_MODE: 15592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case MIXED_MODE: 15602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 15612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 15622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_UNABLE_TO_SET_PARAM); 15632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (self == NULL) 15652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_HANDLE); 156647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.dualChannelMode = (DUAL_CHANNEL_MODE)value; 156747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->applyProcessing = 1; /* Force processing */ 156847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 156947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 157047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case DMX_PSEUDO_SURROUND_MODE: 157147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch ((PSEUDO_SURROUND_MODE)value) { 157247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case NEVER_DO_PS_DMX: 157347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case AUTO_PS_DMX: 157447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case FORCE_PS_DMX: 157547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 157647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 157747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_UNABLE_TO_SET_PARAM); 157847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 157947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (self == NULL) 158047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_INVALID_HANDLE); 158147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self->userParams.pseudoSurrMode = (PSEUDO_SURROUND_MODE)value; 15822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 15832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 15852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_UNKNOWN_PARAM); 15862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_OK); 15892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 15902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 159147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/** Get one parameter value of one PCM downmix module instance. 15922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Handle of PCM downmix module instance. 159347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Parameter to be set. 159447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [out] Pointer to buffer receiving the parameter value. 15952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 15962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 159747c680c62246594107da0a8995c953dfb8040bceJean-Michel TriviPCMDMX_ERROR pcmDmx_GetParam ( 15982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX self, 159947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const PCMDMX_PARAM param, 160047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT * const pValue 160147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ) 160247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 160347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_USER_PARAMS *pUsrParams; 160447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 160547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (self == NULL) 160647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (pValue == NULL) ) { 160747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_INVALID_HANDLE); 160847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 160947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pUsrParams = &self->userParams; 161047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 161147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (param) 161247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { 161347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case DMX_BS_DATA_EXPIRY_FRAME: 161447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pValue = (INT)pUsrParams->expiryFrame; 161547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 161647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case DMX_BS_DATA_DELAY: 161747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pValue = (INT)pUsrParams->frameDelay; 161847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 161947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case MIN_NUMBER_OF_OUTPUT_CHANNELS: 162047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pValue = (INT)pUsrParams->numOutChannelsMin; 162147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 162247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case MAX_NUMBER_OF_OUTPUT_CHANNELS: 162347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pValue = (INT)pUsrParams->numOutChannelsMax; 162447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 162547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case DMX_DUAL_CHANNEL_MODE: 162647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pValue = (INT)pUsrParams->dualChannelMode; 162747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 162847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case DMX_PSEUDO_SURROUND_MODE: 162947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pValue = (INT)pUsrParams->pseudoSurrMode; 163047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 163147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 163247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_UNKNOWN_PARAM); 163347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 163447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 163547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_OK); 163647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} 163747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 163847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 163947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef DSE_METADATA_ENABLE 164047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 164147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define MAX_DSE_ANC_BYTES ( 16 ) /* 15 bytes */ 164247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define ANC_DATA_SYNC_BYTE ( 0xBC ) /* ancillary data sync byte. */ 164347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 164447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* 164547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * Read DMX meta-data from a data stream element. 164647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi */ 164747c680c62246594107da0a8995c953dfb8040bceJean-Michel TriviPCMDMX_ERROR pcmDmx_Parse ( 164847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi HANDLE_PCM_DOWNMIX self, 164947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi HANDLE_FDK_BITSTREAM hBs, 165047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT ancDataBits, 16512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int isMpeg2 16522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 16532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 165447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCMDMX_ERROR errorStatus = PCMDMX_OK; 165547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi DMX_BS_META_DATA *pBsMetaData = &self->bsMetaData[0]; 16562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 165747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int skip4Dmx = 0, skip4Ext = 0; 165847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int dmxLvlAvail = 0, extDataAvail = 0; 165947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int foundNewData = 0; 166047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT minAncBits = ((isMpeg2) ? 5 : 3)*8; 16612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 166247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (self == NULL) 166347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (hBs == NULL) ) { return (PCMDMX_INVALID_HANDLE); } 166447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 166547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ancDataBits = FDKgetValidBits(hBs); 16662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* sanity checks */ 166847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (ancDataBits < minAncBits) 166947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (ancDataBits > FDKgetValidBits(hBs)) ) { 16702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_CORRUPT_ANC_DATA); 16712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 167347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData = &self->bsMetaData[0]; 167447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 167547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (isMpeg2) { 167647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* skip DVD ancillary data */ 167747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKpushFor(hBs, 16); 167847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 167947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 16802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* check sync word */ 168147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBits(hBs,8) != ANC_DATA_SYNC_BYTE) { 16822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_CORRUPT_ANC_DATA); 16832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 168547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* skip MPEG audio type and Dolby surround mode */ 168647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKpushFor(hBs, 4); 16872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (isMpeg2) { 168947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* int numAncBytes = */ FDKreadBits(hBs, 4); 169047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* advanced dynamic range control */ 169147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) skip4Dmx += 24; 169247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* dialog normalization */ 169347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) skip4Dmx += 8; 169447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* reproduction_level */ 169547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) skip4Dmx += 8; 169647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 169747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKpushFor(hBs, 2); /* drc presentation mode */ 169847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->pseudoSurround = FDKreadBit(hBs); 169947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKpushFor(hBs, 4); /* reserved bits */ 17002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 170147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 170247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* downmixing levels MPEGx status */ 170347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxLvlAvail = FDKreadBit(hBs); 170447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 170547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (isMpeg2) { 170647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* scale factor CRC status */ 170747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) skip4Ext += 16; 170847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 170947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* ancillary data extension status */ 171047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi extDataAvail = FDKreadBit(hBs); 17112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 17122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 171347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* audio coding and compression status */ 171447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) skip4Ext += 16; 171547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* coarse grain timecode status */ 171647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) skip4Ext += 16; 171747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* fine grain timecode status */ 171847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) skip4Ext += 16; 171947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 172047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* skip the useless data to get to the DMX levels */ 172147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKpushFor(hBs, skip4Dmx); 172247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 17232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* downmix_levels_MPEGX */ 172447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (dmxLvlAvail) 17252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 172647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) { /* center_mix_level_on */ 172747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->cLevIdx = FDKreadBits(hBs, 3); 17282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project foundNewData = 1; 17292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 173047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBits(hBs, 3); 17312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 173247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (FDKreadBit(hBs)) { /* surround_mix_level_on */ 173347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->sLevIdx = FDKreadBits(hBs, 3); 17342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project foundNewData = 1; 17352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 173647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBits(hBs, 3); 173747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 173847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 173947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 174047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* skip the useless data to get to the ancillary data extension */ 174147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKpushFor(hBs, skip4Ext); 174247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 174347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* anc data extension (MPEG-4 only) */ 174447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (extDataAvail) { 174547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int extDmxLvlSt, extDmxGainSt, extDmxLfeSt; 174647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 174747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBit(hBs); /* reserved bit */ 174847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi extDmxLvlSt = FDKreadBit(hBs); 174947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi extDmxGainSt = FDKreadBit(hBs); 175047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi extDmxLfeSt = FDKreadBit(hBs); 175147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBits(hBs, 4); /* reserved bits */ 175247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 175347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (extDmxLvlSt) { 175447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->dmixIdxA = FDKreadBits(hBs, 3); 175547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->dmixIdxB = FDKreadBits(hBs, 3); 175647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBits(hBs, 2); /* reserved bits */ 175747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi foundNewData = 1; 175847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 175947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (extDmxGainSt) { 176047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->dmxGainIdx5 = FDKreadBits(hBs, 7); 176147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBit(hBs); /* reserved bit */ 176247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->dmxGainIdx2 = FDKreadBits(hBs, 7); 176347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBit(hBs); /* reserved bit */ 176447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi foundNewData = 1; 176547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 176647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (extDmxLfeSt) { 176747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->dmixIdxLfe = FDKreadBits(hBs, 4); 176847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKreadBits(hBs, 4); /* reserved bits */ 176947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi foundNewData = 1; 17702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 177147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 17722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 177347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* final sanity check on the amount of read data */ 177447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ((INT)FDKgetValidBits(hBs) < 0) { 177547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi errorStatus = PCMDMX_CORRUPT_ANC_DATA; 17762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 17772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 177847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (errorStatus == PCMDMX_OK) 177947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (foundNewData == 1) ) { 178047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* announce new data */ 178147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->typeFlags |= TYPE_DSE_DATA; 178247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* reset expiry counter */ 178347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->expiryCount = 0; 178447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 17852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 178647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (errorStatus); 178747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi} 178847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 178947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/* 179047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * Read DMX meta-data from a data stream element. 179147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi */ 179247c680c62246594107da0a8995c953dfb8040bceJean-Michel TriviPCMDMX_ERROR pcmDmx_ReadDvbAncData ( 179347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi HANDLE_PCM_DOWNMIX self, 179447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR *pAncDataBuf, 179547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT ancDataBytes, 179647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int isMpeg2 179747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ) 179847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{ 179947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_BITSTREAM bs; 180047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi HANDLE_FDK_BITSTREAM hBs = &bs; 180147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCMDMX_ERROR errorStatus = PCMDMX_OK; 180247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 180347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (self == NULL) { return (PCMDMX_INVALID_HANDLE); } 180447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 180547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* sanity checks */ 180647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (pAncDataBuf == NULL) 180747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (ancDataBytes == 0) ) { 180847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_CORRUPT_ANC_DATA); 180947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 181047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 181147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKinitBitStream (hBs, pAncDataBuf, MAX_DSE_ANC_BYTES, ancDataBytes*8, BS_READER); 181247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 181347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi errorStatus = pcmDmx_Parse ( 181447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi self, 181547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi hBs, 181647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ancDataBytes*8, 181747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi isMpeg2 ); 181847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 181947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (errorStatus); 18202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 182147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* DSE_METADATA_ENABLE */ 18222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 182347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCE_METADATA_ENABLE 18242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Set the matrix mixdown information extracted from the PCE of an AAC bitstream. 18252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * Note: Call only if matrix_mixdown_idx_present is true. 18262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Handle of PCM downmix module instance. 18272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] The 2 bit matrix mixdown index extracted from PCE. 18282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] The pseudo surround enable flag extracted from PCE. 18292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 18302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 18312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPCMDMX_ERROR pcmDmx_SetMatrixMixdownFromPce ( 18322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX self, 18332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int matrixMixdownPresent, 18342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int matrixMixdownIdx, 18352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int pseudoSurroundEnable 18362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 18372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 183847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi DMX_BS_META_DATA *pBsMetaData = &self->bsMetaData[0]; 18392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (self == NULL) { 18412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_HANDLE); 18422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (matrixMixdownPresent) { 184547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->pseudoSurround = pseudoSurroundEnable; 184647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->matrixMixdownIdx = matrixMixdownIdx & 0x03; 184747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->typeFlags |= TYPE_PCE_DATA; 184847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Reset expiry counter */ 184947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pBsMetaData->expiryCount = 0; 18502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_OK); 18532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 185447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* PCE_METADATA_ENABLE */ 18552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Apply down or up mixing. 18582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Handle of PCM downmix module instance. 185947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [inout] Pointer to buffer that hold the time domain signal. 18602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Pointer where the amount of output samples is returned into. 18612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [inout] Pointer where the amount of output channels is returned into. 18622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [in] Flag which indicates if output time data are writtern interleaved or as subsequent blocks. 18632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [inout] Array where the corresponding channel type for each output audio channel is stored into. 18642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [inout] Array where the corresponding channel type index for each output audio channel is stored into. 186547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [in] Array containing the out channel mapping to be used (From MPEG PCE ordering to whatever is required). 186647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * @param [out] Pointer on a field receiving the scale factor that has to be applied on all samples afterwards. 186747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * If the handed pointer is NULL scaling is done internally. 18682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 18692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 18702228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPCMDMX_ERROR pcmDmx_ApplyFrame ( 18712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX self, 18722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project INT_PCM *pPcmBuf, 18732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UINT frameSize, 18742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project INT *nChannels, 18752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int fInterleaved, 18762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project AUDIO_CHANNEL_TYPE channelType[], 18772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR channelIndices[], 187847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi const UCHAR channelMapping[][8], 187947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT *pDmxOutScale 18802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 18812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 188247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_USER_PARAMS *pParam = NULL; 18832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project PCMDMX_ERROR errorStatus = PCMDMX_OK; 18842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project DUAL_CHANNEL_MODE dualChannelMode; 18852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project PCM_DMX_CHANNEL_MODE inChMode; 188647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCM_DMX_CHANNEL_MODE outChMode; 188747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT devNull; /* Just a dummy to avoid a lot of branches in the code */ 188847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int numOutChannels, numInChannels; 188947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int inStride, outStride, offset; 189047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int dmxMaxScale, dmxScale; 189147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int ch, slot; 18922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR inOffsetTable[PCM_DMX_MAX_CHANNELS]; 18932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 189447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi DMX_BS_META_DATA bsMetaData; 18952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 189647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (self == NULL) 189747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (nChannels == NULL) 189847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (channelType == NULL) 189947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (channelIndices == NULL) 190047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (channelMapping == NULL) ) { 190147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (PCMDMX_INVALID_HANDLE); 19022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 190447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Init the output scaling */ 190547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxScale = 0; 190647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (pDmxOutScale != NULL) { 190747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Avoid final scaling internally and hand it to the outside world. */ 190847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pDmxOutScale = 0; 190947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxMaxScale = PCMDMX_MAX_HEADROOM; 191047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 191147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Apply the scaling internally. */ 191247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pDmxOutScale = &devNull; /* redirect to temporal stack memory */ 191347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxMaxScale = 0; 19142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 191647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParam = &self->userParams; 191747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numInChannels = *nChannels; 19182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 191947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Perform some input sanity checks */ 19202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pPcmBuf == NULL) { return (PCMDMX_INVALID_ARGUMENT); } 19212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (frameSize == 0) { return (PCMDMX_INVALID_ARGUMENT); } 192247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (numInChannels == 0) 192347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (numInChannels > PCM_DMX_MAX_IN_CHANNELS) ) 192447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { return (PCMDMX_INVALID_ARGUMENT); } 192547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 192647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Check on misconfiguration */ 192747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT( (pParam->numOutChannelsMax <= 0) \ 192847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (pParam->numOutChannelsMax >= pParam->numOutChannelsMin)); 192947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 193047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Determine if the module has to do processing */ 193147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (self->applyProcessing == 0) 193247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && ((pParam->numOutChannelsMax <= 0) 193347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (pParam->numOutChannelsMax >= numInChannels)) 193447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (pParam->numOutChannelsMin <= numInChannels) ) { 193547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Nothing to do */ 193647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi return (errorStatus); 193747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 19382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 193947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Determine the number of output channels */ 194047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (pParam->numOutChannelsMax > 0) 194147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (numInChannels > pParam->numOutChannelsMax) ) { 194247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numOutChannels = pParam->numOutChannelsMax; 194347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 194447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else if (numInChannels < pParam->numOutChannelsMin) { 194547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numOutChannels = pParam->numOutChannelsMin; 194647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 194747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else { 19482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numOutChannels = numInChannels; 19492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 195047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 195147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dualChannelMode = pParam->dualChannelMode; 19522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Analyse input channel configuration and get channel offset 19542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * table that can be accessed with the fixed channel labels. */ 195547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi errorStatus = getChannelMode( 19562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project numInChannels, 19572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelType, 19582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelIndices, 195947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inOffsetTable, 196047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi &inChMode 19612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ); 196247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( PCMDMX_IS_FATAL_ERROR(errorStatus) 196347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi || (inChMode == CH_MODE_UNDEFINED) ) { 19642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* We don't need to restore because the channel 19652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project configuration has not been changed. Just exit. */ 19662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_CH_CONFIG); 19672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 196947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set input stride and offset */ 197047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (fInterleaved) { 197147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inStride = numInChannels; 197247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi offset = 1; /* Channel specific offset factor */ 197347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 197447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inStride = 1; 197547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi offset = frameSize; /* Channel specific offset factor */ 197647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 197747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 197847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Reset downmix meta data if necessary */ 197947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (pParam->expiryFrame > 0) 198047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (++self->bsMetaData[0].expiryCount > pParam->expiryFrame) ) 198147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* The metadata read from bitstream is too old. */ 198247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi PCMDMX_ERROR err = pcmDmx_Reset(self, PCMDMX_RESET_BS_DATA); 198347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(err == PCMDMX_OK); 198447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 198547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(&bsMetaData, &self->bsMetaData[pParam->frameDelay], sizeof(DMX_BS_META_DATA)); 198647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Maintain delay line */ 198747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (slot = pParam->frameDelay; slot > 0; slot -= 1) { 198847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(&self->bsMetaData[slot], &self->bsMetaData[slot-1], sizeof(DMX_BS_META_DATA)); 198947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 199047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 19912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 199247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCM_DOWNMIX_ENABLE 19932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( numInChannels > numOutChannels ) 19942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { /* Apply downmix */ 199547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pInPcm[PCM_DMX_MAX_IN_CHANNELS] = { NULL }; 199647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pOutPcm[PCM_DMX_MAX_OUT_CHANNELS] = { NULL }; 199747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX mixFactors[PCM_DMX_MAX_CHANNELS][PCM_DMX_MAX_CHANNELS]; 199847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR outOffsetTable[PCM_DMX_MAX_CHANNELS]; 199947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT sample; 200047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int chCfg = 0; 200147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int bypScale = 0; 200247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 200347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_IN_CHANNELS >= 7) 200447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numInChannels > SIX_CHANNEL) { 200547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi AUDIO_CHANNEL_TYPE multiPurposeChType[2]; 200647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 200747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Get the type of the multipurpose channels */ 200847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi multiPurposeChType[0] = channelType[inOffsetTable[LEFT_MULTIPRPS_CHANNEL]]; 200947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi multiPurposeChType[1] = channelType[inOffsetTable[RIGHT_MULTIPRPS_CHANNEL]]; 201047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 201147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Check if the input configuration is one defined in the standard. */ 201247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi switch (inChMode) { 201347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_5_0_2_1: /* chCfg 7 || 14 */ 201447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Further analyse the input config to distinguish the two CH_MODE_5_0_2_1 configs. */ 201547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (multiPurposeChType[0] == ACT_FRONT_TOP) 201647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (multiPurposeChType[1] == ACT_FRONT_TOP) ) { 201747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chCfg = 14; 201847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else { 201947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chCfg = 7; 202047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 202147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 202247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_3_1: /* chCfg 11 */ 202347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chCfg = 11; 202447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 202547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi case CH_MODE_3_0_4_1: /* chCfg 12 */ 202647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chCfg = 12; 202747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 202847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi default: 202947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi chCfg = 0; /* Not a known config */ 203047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 203147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 20322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 203347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 20342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 203547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set this stages output stride and channel mode: */ 203647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outStride = (fInterleaved) ? numOutChannels : 1; 203747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outChMode = outChModeTable[numOutChannels]; 203847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 203947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Get channel description and channel mapping for the desired output configuration. */ 20402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project getChannelDescription( 204147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outChMode, 20422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelMapping, 20432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelType, 20442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelIndices, 20452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outOffsetTable 20462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ); 20472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Now there is no way back because we modified the channel configuration! */ 20482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 204947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Create the DMX matrix */ 205047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi errorStatus = getMixFactors ( 205147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi (chCfg>0) ? 1 : 0, 205247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi (chCfg>0) ? (PCM_DMX_CHANNEL_MODE)chCfg : inChMode, 205347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outChMode, 205447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pParam, 205547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi &bsMetaData, 205647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors, 205747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi &dmxScale 205847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ); 205947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* No fatal errors can occur here. The function is designed to always return a valid matrix. 206047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi The error code is used to signal configurations and matrices that are not conform to any standard. */ 206147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 206247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Determine the final scaling */ 206347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi bypScale = FDKmin(dmxMaxScale, dmxScale); 206447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pDmxOutScale += bypScale; 206547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi dmxScale -= bypScale; 206647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 206747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Set channel pointer for input. Remove empty cols. */ 206847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int inCh, outCh, map[PCM_DMX_MAX_CHANNELS]; 206947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ch = 0; 207047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < PCM_DMX_MAX_CHANNELS; inCh+=1) { 207147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (inOffsetTable[inCh] != 255) { 207247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[ch] = &pPcmBuf[inOffsetTable[inCh]*offset]; 207347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi map[ch++] = inCh; 20742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 207647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(ch == numInChannels); 207747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 207847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Remove unused cols from factor matrix */ 207947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < numInChannels; inCh+=1) { 208047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (inCh != map[inCh]) { 208147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int outCh; 208247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < PCM_DMX_MAX_CHANNELS; outCh+=1) { 208347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi mixFactors[outCh][inCh] = mixFactors[outCh][map[inCh]]; 208447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 208547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 20862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 208847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set channel pointer for output. Remove empty cols. */ 208947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ch = 0; 209047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < PCM_DMX_MAX_CHANNELS; outCh+=1) { 209147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (outOffsetTable[outCh] != 255) { 209247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOutPcm[ch] = &pPcmBuf[outOffsetTable[outCh]*offset]; 209347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi map[ch++] = outCh; 20942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 209647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_ASSERT(ch == numOutChannels); 20972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 209847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Remove unused rows from factor matrix */ 209947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < numOutChannels; outCh+=1) { 210047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (outCh != map[outCh]) { 210147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(&mixFactors[outCh], &mixFactors[map[outCh]], PCM_DMX_MAX_CHANNELS*sizeof(FIXP_DMX)); 21022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 210447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 21052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 210647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Sample processing loop */ 210747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (sample = 0; sample < frameSize; sample++) 210847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { 210947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_PCM tIn[PCM_DMX_MAX_IN_CHANNELS]; 211047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DBL tOut[PCM_DMX_MAX_OUT_CHANNELS] = { (FIXP_DBL)0 }; 211147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int inCh, outCh; 211247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 211347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Preload all input samples */ 211447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < numInChannels; inCh+=1) { 211547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi tIn[inCh] = (FIXP_PCM)*pInPcm[inCh]; 211647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[inCh] += inStride; 21172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 211847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Apply downmix coefficients to input samples and accumulate for output */ 211947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh=0; outCh < numOutChannels; outCh+=1) { 212047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (inCh=0; inCh < numInChannels; inCh+=1) { 212147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi tOut[outCh] += fMult(tIn[inCh], mixFactors[outCh][inCh]); 212247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 212347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Write sample */ 212447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (SAMPLE_BITS == DFRACT_BITS) 212547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pOutPcm[outCh] = (INT_PCM)SATURATE_LEFT_SHIFT(tOut[outCh], dmxScale, SAMPLE_BITS); 21262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else 212747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pOutPcm[outCh] = (INT_PCM)SATURATE_RIGHT_SHIFT(tOut[outCh], DFRACT_BITS-SAMPLE_BITS-dmxScale, SAMPLE_BITS); 21282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 212947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOutPcm[outCh] += outStride; 21302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 213347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Update the number of output channels */ 213447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *nChannels = numOutChannels; 21352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 213647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 213747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else 213847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* PCM_DOWNMIX_ENABLE */ 213947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCM_CHANNEL_EXTENSION_ENABLE 214047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( numInChannels < numOutChannels ) 214147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Apply rudimentary upmix */ 214247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set up channel pointer */ 214347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UINT sample; 214447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR outOffsetTable[PCM_DMX_MAX_CHANNELS]; 214547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 214647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* FIRST STAGE 214747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Create a stereo/dual channel signal */ 214847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numInChannels == ONE_CHANNEL) 214947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { 215047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pInPcm[PCM_DMX_MAX_CHANNELS]; 215147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pOutLF, *pOutRF; 21522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 215347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set this stages output stride and channel mode: */ 215447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outStride = (fInterleaved) ? TWO_CHANNEL : 1; 215547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outChMode = outChModeTable[TWO_CHANNEL]; 21562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Get channel description and channel mapping for this 215847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * stages number of output channels (always STEREO). */ 21592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project getChannelDescription( 216047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outChMode, 21612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelMapping, 21622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelType, 21632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project channelIndices, 21642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outOffsetTable 21652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ); 216647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Now there is no way back because we modified the channel configuration! */ 21672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 216847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set input channel pointer. The first channel is always at index 0. */ 216947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[CENTER_FRONT_CHANNEL] = &pPcmBuf[(frameSize-1)*inStride]; /* Considering input mapping could lead to a invalid pointer 217047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi here if the channel is not declared to be a front channel. */ 21712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 217247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set output channel pointer (for this stage). */ 217347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOutLF = &pPcmBuf[outOffsetTable[LEFT_FRONT_CHANNEL]*offset+(frameSize-1)*outStride]; 217447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOutRF = &pPcmBuf[outOffsetTable[RIGHT_FRONT_CHANNEL]*offset+(frameSize-1)*outStride]; 21752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 217647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* 1/0 input: */ 21772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (sample = 0; sample < frameSize; sample++) { 217847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* L' = C; R' = C; */ 217947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pOutLF = *pOutRF = *pInPcm[CENTER_FRONT_CHANNEL]; 21802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 218147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[CENTER_FRONT_CHANNEL] -= inStride; 218247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOutLF -= outStride; pOutRF -= outStride; 21832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 218447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 218547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Prepare for next stage: */ 218647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inStride = outStride; 218747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inChMode = outChMode; 218847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(inOffsetTable, outOffsetTable, PCM_DMX_MAX_CHANNELS*sizeof(UCHAR)); 21892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 219147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#if (PCM_DMX_MAX_OUT_CHANNELS > 2) 219247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* SECOND STAGE 219347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Extend with zero channels to achieved the desired number of output channels. */ 219447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numOutChannels > TWO_CHANNEL) 219547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { 219647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pIn[PCM_DMX_MAX_CHANNELS] = { NULL }; 219747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pOut[PCM_DMX_MAX_CHANNELS] = { NULL }; 219847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi AUDIO_CHANNEL_TYPE inChTypes[PCM_DMX_MAX_CHANNELS]; 219947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR inChIndices[PCM_DMX_MAX_CHANNELS]; 220047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi UCHAR numChPerGrp[2][PCM_DMX_MAX_CHANNEL_GROUPS]; 220147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int nContentCh = 0; /* Number of channels with content */ 220247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int nEmptyCh = 0; /* Number of channels with content */ 220347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int ch, chGrp, isCompatible = 1; 220447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 220547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Do not change the signalling which is the channel types and indices. 220647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Just reorder and add channels. So first save the input signalling. */ 220747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(inChTypes, channelType, PCM_DMX_MAX_CHANNELS*sizeof(AUDIO_CHANNEL_TYPE)); 220847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(inChIndices, channelIndices, PCM_DMX_MAX_CHANNELS*sizeof(UCHAR)); 220947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 221047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set this stages output stride and channel mode: */ 221147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outStride = (fInterleaved) ? numOutChannels : 1; 221247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outChMode = outChModeTable[numOutChannels]; 221347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 221447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Check if input channel config can be easily mapped to the desired output config. */ 221547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (chGrp = 0; chGrp < PCM_DMX_MAX_CHANNEL_GROUPS; chGrp += 1) { 221647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numChPerGrp[IN][chGrp] = (inChMode >> (chGrp*4)) & 0xF; 221747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi numChPerGrp[OUT][chGrp] = (outChMode >> (chGrp*4)) & 0xF; 221847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 221947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numChPerGrp[IN][chGrp] > numChPerGrp[OUT][chGrp]) { 222047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi isCompatible = 0; 222147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 222247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 222347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 22242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 222547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( isCompatible ) { 222647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Get new channel description and channel 222747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * mapping for the desired output channel mode. */ 222847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi getChannelDescription( 222947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outChMode, 223047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelMapping, 223147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelType, 223247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelIndices, 223347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outOffsetTable 223447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi ); 223547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* If the input config has a back center channel but the output 223647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi config has not, copy it to left and right (if available). */ 223747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (numChPerGrp[IN][CH_GROUP_REAR]%2) 223847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && !(numChPerGrp[OUT][CH_GROUP_REAR]%2) ) { 223947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (numChPerGrp[IN][CH_GROUP_REAR] == 1) { 224047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inOffsetTable[RIGHT_REAR_CHANNEL] = inOffsetTable[LEFT_REAR_CHANNEL]; 224147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } else if (numChPerGrp[IN][CH_GROUP_REAR] == 3) { 224247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inOffsetTable[RIGHT_MULTIPRPS_CHANNEL] = inOffsetTable[LEFT_MULTIPRPS_CHANNEL]; 224347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 224447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 224547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 224647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else { 224747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Just copy and extend the original config */ 224847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDKmemcpy(outOffsetTable, inOffsetTable, PCM_DMX_MAX_CHANNELS*sizeof(UCHAR)); 224947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 225047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 225147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set I/O channel pointer. 225247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Note: The following assignment algorithm clears the channel offset tables. 225347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi Thus they can not be used afterwards. */ 225447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = 0; ch < PCM_DMX_MAX_CHANNELS; ch+=1) { 225547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( (outOffsetTable[ch] < 255) 225647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi && (inOffsetTable[ch] < 255) ) 225747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi { /* Set I/O pointer: */ 225847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pIn[nContentCh] = &pPcmBuf[inOffsetTable[ch]*offset+(frameSize-1)*inStride]; 225947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOut[nContentCh] = &pPcmBuf[outOffsetTable[ch]*offset+(frameSize-1)*outStride]; 226047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Update signalling */ 226147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelType[outOffsetTable[ch]] = inChTypes[inOffsetTable[ch]]; 226247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelIndices[outOffsetTable[ch]] = inChIndices[inOffsetTable[ch]]; 226347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inOffsetTable[ch] = 255; 226447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outOffsetTable[ch] = 255; 226547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi nContentCh += 1; 226647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 226747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 226847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if ( isCompatible ) { 226947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Assign the remaining input channels. 227047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi This is just a safety appliance. We should never need it. */ 227147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = 0; ch < PCM_DMX_MAX_CHANNELS; ch+=1) { 227247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (inOffsetTable[ch] < 255) { 227347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi int outCh; 227447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (outCh = 0 ; outCh < PCM_DMX_MAX_CHANNELS; outCh += 1) { 227547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (outOffsetTable[outCh] < 255) { 227647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi break; 227747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 227847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 227947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set I/O pointer: */ 228047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pIn[nContentCh] = &pPcmBuf[inOffsetTable[ch]*offset+(frameSize-1)*inStride]; 228147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOut[nContentCh] = &pPcmBuf[outOffsetTable[outCh]*offset+(frameSize-1)*outStride]; 228247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Update signalling */ 228347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelType[outOffsetTable[outCh]] = inChTypes[inOffsetTable[ch]]; 228447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelIndices[outOffsetTable[outCh]] = inChIndices[inOffsetTable[ch]]; 228547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi inOffsetTable[ch] = 255; 228647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outOffsetTable[outCh] = 255; 228747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi nContentCh += 1; 228847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 228947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 229047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set the remaining output channel pointer */ 229147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = 0; ch < PCM_DMX_MAX_CHANNELS; ch+=1) { 229247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi if (outOffsetTable[ch] < 255) { 229347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOut[nContentCh+nEmptyCh] = &pPcmBuf[outOffsetTable[ch]*offset+(frameSize-1)*outStride]; 229447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Expand output signalling */ 229547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelType[outOffsetTable[ch]] = ACT_NONE; 229647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelIndices[outOffsetTable[ch]] = nEmptyCh; 229747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi outOffsetTable[ch] = 255; 229847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi nEmptyCh += 1; 229947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 230047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 230147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 230247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi else { 230347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Set the remaining output channel pointer */ 230447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = nContentCh; ch < numOutChannels; ch+=1) { 230547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOut[ch] = &pPcmBuf[ch*offset+(frameSize-1)*outStride]; 230647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Expand output signalling */ 230747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelType[ch] = ACT_NONE; 230847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi channelIndices[ch] = nEmptyCh; 230947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi nEmptyCh += 1; 231047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 231147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 231247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 231347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* First copy the channels that have signal */ 231447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (sample = 0; sample < frameSize; sample+=1) { 231547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM tIn[PCM_DMX_MAX_CHANNELS]; 231647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Read all channel samples */ 231747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = 0; ch < nContentCh; ch+=1) { 231847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi tIn[ch] = *pIn[ch]; 231947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pIn[ch] -= inStride; 232047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 232147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Write all channel samples */ 232247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = 0; ch < nContentCh; ch+=1) { 232347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pOut[ch] = tIn[ch]; 232447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOut[ch] -= outStride; 232547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 232647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 232747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 232847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Clear all the other channels */ 232947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (sample = 0; sample < frameSize; sample++) { 233047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi for (ch = nContentCh; ch < numOutChannels; ch+=1) { 233147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pOut[ch] = (INT_PCM)0; 233247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOut[ch] -= outStride; 233347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 233447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 233547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi } 233647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* if (PCM_DMX_MAX_OUT_CHANNELS > 2) */ 233747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 233847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* update the number of output channels */ 233947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *nChannels = numOutChannels; 23402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 23412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 234247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* PCM_CHANNEL_EXTENSION_ENABLE */ 23432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( numInChannels == numOutChannels ) 23442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 23452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Don't need to change the channel description here */ 23462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (numInChannels) 23482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 23492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 2: 23502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { /* Set up channel pointer */ 235147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pInPcm[PCM_DMX_MAX_CHANNELS]; 235247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi INT_PCM *pOutL, *pOutR; 235347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FIXP_DMX flev; 23542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UINT sample; 23562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int inStride, outStride, offset; 23572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (fInterleaved) { 23592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project inStride = numInChannels; 23602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outStride = 2; /* fixed !!! (below stereo is donwmixed to mono if required */ 23612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project offset = 1; /* Channel specific offset factor */ 23622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 23632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project inStride = 1; 23642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project outStride = 1; 23652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project offset = frameSize; /* Channel specific offset factor */ 23662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 23672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Set input channel pointer */ 236947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[LEFT_FRONT_CHANNEL] = &pPcmBuf[inOffsetTable[LEFT_FRONT_CHANNEL]*offset]; 237047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[RIGHT_FRONT_CHANNEL] = &pPcmBuf[inOffsetTable[RIGHT_FRONT_CHANNEL]*offset]; 23712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Set output channel pointer (same as input) */ 237347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOutL = pInPcm[LEFT_FRONT_CHANNEL]; 237447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pOutR = pInPcm[RIGHT_FRONT_CHANNEL]; 23752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Set downmix levels: */ 237747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi flev = FL2FXCONST_DMX(0.70710678f); 23782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2/0 input: */ 23792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (dualChannelMode) 23802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 23812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH1_MODE: /* L' = 0.707 * Ch1; R' = 0.707 * Ch1 */ 23822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (sample = 0; sample < frameSize; sample++) { 23832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *pOutL = *pOutR = 238447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi (INT_PCM)SATURATE_RIGHT_SHIFT(fMult((FIXP_PCM)*pInPcm[LEFT_FRONT_CHANNEL], flev), DFRACT_BITS-SAMPLE_BITS, SAMPLE_BITS); 23852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 238647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[LEFT_FRONT_CHANNEL] += inStride; 23872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pOutL += outStride; pOutR += outStride; 23882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 23892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 23902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case CH2_MODE: /* L' = 0.707 * Ch2; R' = 0.707 * Ch2 */ 23912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (sample = 0; sample < frameSize; sample++) { 23922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *pOutL = *pOutR = 239347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi (INT_PCM)SATURATE_RIGHT_SHIFT(fMult((FIXP_PCM)*pInPcm[RIGHT_FRONT_CHANNEL], flev), DFRACT_BITS-SAMPLE_BITS, SAMPLE_BITS); 23942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 239547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[RIGHT_FRONT_CHANNEL] += inStride; 23962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pOutL += outStride; pOutR += outStride; 23972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 23982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 23992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case MIXED_MODE: /* L' = 0.5*Ch1 + 0.5*Ch2; R' = 0.5*Ch1 + 0.5*Ch2 */ 24002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (sample = 0; sample < frameSize; sample++) { 240147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi *pOutL = *pOutR = (*pInPcm[LEFT_FRONT_CHANNEL] >> 1) + (*pInPcm[RIGHT_FRONT_CHANNEL] >> 1); 24022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 240347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi pInPcm[LEFT_FRONT_CHANNEL] += inStride; pInPcm[RIGHT_FRONT_CHANNEL] += inStride; 24042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pOutL += outStride; pOutR += outStride; 24052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 24072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 24082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case STEREO_MODE: 24092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* nothing to do */ 24102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 24112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 24142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project default: 24162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* nothing to do */ 24172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 24182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (errorStatus); 24222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 24232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Close an instance of the PCM downmix module. 24262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [inout] Pointer to a buffer containing the handle of the instance. 24272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 24282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project **/ 24292228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPCMDMX_ERROR pcmDmx_Close ( 24302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_PCM_DOWNMIX *pSelf 24312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 24322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 24332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pSelf == NULL) { 24342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_INVALID_HANDLE); 24352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FreePcmDmxInstance( pSelf ); 24382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *pSelf = NULL; 24392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return (PCMDMX_OK); 24412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 24422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/** Get library info for this module. 24452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @param [out] Pointer to an allocated LIB_INFO structure. 24462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * @returns Returns an error code. 24472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 24482228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPCMDMX_ERROR pcmDmx_GetLibInfo( LIB_INFO *info ) 24492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 24502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i; 24512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (info == NULL) { 24532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return PCMDMX_INVALID_ARGUMENT; 24542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Search for next free tab */ 24572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < FDK_MODULE_LAST; i++) { 24582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (info[i].module_id == FDK_NONE) break; 24592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (i == FDK_MODULE_LAST) { 24612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return PCMDMX_UNKNOWN; 24622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 24632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add the library info */ 246547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi info[i].module_id = FDK_PCMDMX; 246647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi info[i].version = LIB_VERSION(PCMDMX_LIB_VL0, PCMDMX_LIB_VL1, PCMDMX_LIB_VL2); 246747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi LIB_VERSION_STRING(info+i); 246847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi info[i].build_date = PCMDMX_LIB_BUILD_DATE; 246947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi info[i].build_time = PCMDMX_LIB_BUILD_TIME; 247047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi info[i].title = PCMDMX_LIB_TITLE; 24712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Set flags */ 247347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi info[i].flags = 0 247447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCM_DOWNMIX_ENABLE 24752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project | CAPF_DMX_BLIND /* At least blind downmixing is possible */ 247647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #ifdef PCE_METADATA_ENABLE 24772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project | CAPF_DMX_PCE /* Guided downmix with data from MPEG-2/4 Program Config Elements (PCE). */ 247847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #ifdef ARIB_MIXDOWN_ENABLE 247947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi | CAPF_DMX_ARIB /* PCE guided downmix with slightly different equations and levels. */ 248047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #endif 248147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #endif /* PCE_METADATA_ENABLE */ 248247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #ifdef DSE_METADATA_ENABLE 24832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project | CAPF_DMX_DVB /* Guided downmix with data from DVB ancillary data fields. */ 248447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi #endif 248547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif /* PCM_DOWNMIX_ENABLE */ 248647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef PCM_CHANNEL_EXTENSION_ENABLE 248747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi | CAPF_DMX_CH_EXP /* Simple upmixing by dublicating channels or adding zero channels. */ 248847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif 24892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ; 24902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 249147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi /* Add lib info for FDK tools (if not yet done). */ 249247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi FDK_toolsGetLibInfo(info); 249347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi 24942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return PCMDMX_OK; 24952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 24962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 24982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2499