1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/**
17*************************************************************************
18 * @file    M4AD_Null.c
19 * @brief   Implementation of the MP3 decoder public interface
20 * @note    This file implements a "null" audio decoder, that is a decoder
21 *          that do nothing except getting AU from the reader
22*************************************************************************
23*/
24#include "M4OSA_Debug.h"
25#include "M4OSA_Error.h"
26#include "M4OSA_Debug.h"
27#include "M4TOOL_VersionInfo.h"
28#include "M4AD_Common.h"
29#include "M4AD_Null.h"
30
31#define M4AD_FORCE_16BITS
32
33/**
34 ************************************************************************
35 * NULL Audio Decoder version information
36 ************************************************************************
37*/
38/* CHANGE_VERSION_HERE */
39#define M4AD_NULL_MAJOR    1
40#define M4AD_NULL_MINOR    1
41#define M4AD_NULL_REVISION 4
42
43/**
44 ************************************************************************
45 * structure    M4AD_NullContext
46 * @brief        Internal null decoder context
47 ************************************************************************
48*/
49typedef struct
50{
51    /**< Pointer to the stream handler provided by the user */
52    M4_AudioStreamHandler*    m_pAudioStreamhandler;
53} M4AD_NullContext;
54
55
56/**
57 ************************************************************************
58 * NXP MP3 decoder functions definition
59 ************************************************************************
60*/
61
62/**
63 ************************************************************************
64 * @brief   Creates an instance of the null decoder
65 * @note    Allocates the context
66 *
67 * @param    pContext:        (OUT)    Context of the decoder
68 * @param    pStreamHandler: (IN)    Pointer to an audio stream description
69 * @param    pUserData:        (IN)    Pointer to User data
70 *
71 * @return    M4NO_ERROR              there is no error
72 * @return    M4ERR_STATE             State automaton is not applied
73 * @return    M4ERR_ALLOC             a memory allocation has failed
74 * @return    M4ERR_PARAMETER         at least one parameter is not properly set (in DEBUG only)
75 ************************************************************************
76*/
77M4OSA_ERR    M4AD_NULL_create(  M4AD_Context* pContext,
78                                M4_AudioStreamHandler *pStreamHandler,
79                                void* pUserData)
80{
81    M4AD_NullContext* pC;
82
83    M4OSA_DEBUG_IF1((pContext == 0), M4ERR_PARAMETER,
84                "M4AD_NULL_create: invalid context pointer");
85    M4OSA_DEBUG_IF1((pStreamHandler == 0), M4ERR_PARAMETER,
86                "M4AD_NULL_create: invalid pointer pStreamHandler");
87
88    pC = (M4AD_NullContext*)M4OSA_32bitAlignedMalloc(sizeof(M4AD_NullContext),
89                 M4DECODER_AUDIO, (M4OSA_Char *)"M4AD_NullContext");
90    if (pC == (M4AD_NullContext*)0)
91    {
92        M4OSA_TRACE1_0("Can not allocate null decoder context");
93        return M4ERR_ALLOC;
94    }
95
96    *pContext = pC;
97
98    pC->m_pAudioStreamhandler = pStreamHandler;
99
100    return M4NO_ERROR;
101}
102
103/**
104 ************************************************************************
105 * @brief    Destroys the instance of the null decoder
106 * @note     After this call the context is invalid
107 *
108 * @param    context:    (IN)    Context of the decoder
109 *
110 * @return   M4NO_ERROR            There is no error
111 * @return   M4ERR_PARAMETER     The context is invalid (in DEBUG only)
112 ************************************************************************
113*/
114M4OSA_ERR    M4AD_NULL_destroy(M4AD_Context context)
115{
116    M4AD_NullContext* pC = (M4AD_NullContext*)context;
117
118    M4OSA_DEBUG_IF1((context == M4OSA_NULL), M4ERR_PARAMETER, "M4AD_NULL_destroy: invalid context");
119
120    free(pC);
121
122    return M4NO_ERROR;
123}
124
125/**
126 ************************************************************************
127 * @brief   Simply output the given audio data
128 * @note
129 *
130 * @param   context:          (IN)    Context of the decoder
131 * @param   pInputBuffer:     (IN/OUT)Input Data buffer. It contains at least one audio frame.
132 *                                    The size of the buffer must be updated inside the function
133 *                                    to reflect the size of the actually decoded data.
134 *                                    (e.g. the first frame in pInputBuffer)
135 * @param   pDecodedPCMBuffer: (OUT)  Output PCM buffer (decoded data).
136 * @param   jumping:           (IN)   M4OSA_TRUE if a jump was just done, M4OSA_FALSE otherwise.
137 * @return    M4NO_ERROR              there is no error
138 * @return    M4ERR_PARAMETER         at least one parameter is not properly set
139 ************************************************************************
140*/
141M4OSA_ERR    M4AD_NULL_step(M4AD_Context context, M4AD_Buffer *pInputBuffer,
142                            M4AD_Buffer *pDecodedPCMBuffer, M4OSA_Bool jumping)
143{
144    M4AD_NullContext* pC = (M4AD_NullContext*)context;
145
146    /*The VPS sends a zero buffer at the end*/
147    if (0 == pInputBuffer->m_bufferSize)
148    {
149        return M4WAR_NO_MORE_AU;
150    }
151
152    if (pInputBuffer->m_bufferSize > pDecodedPCMBuffer->m_bufferSize)
153    {
154        return M4ERR_PARAMETER;
155    }
156#ifdef M4AD_FORCE_16BITS
157    /*if read samples are 8 bits, complete them to 16 bits*/
158    if (pC->m_pAudioStreamhandler->m_byteSampleSize == 1)
159    {
160        M4OSA_UInt32 i;
161        M4OSA_Int16  val;
162
163        for (i = 0; i < pInputBuffer->m_bufferSize; i++)
164        {
165            val = (M4OSA_Int16)((M4OSA_UInt8)(pInputBuffer->m_dataAddress[i]) - 128);
166
167            pDecodedPCMBuffer->m_dataAddress[i*2]   = (M4OSA_Int8)(val>>8);
168            pDecodedPCMBuffer->m_dataAddress[i*2+1] = (M4OSA_Int8)(val&0x00ff);
169        }
170    }
171    else
172    {
173        memcpy((void *)pDecodedPCMBuffer->m_dataAddress, (void *)pInputBuffer->m_dataAddress,
174                    pInputBuffer->m_bufferSize );
175    }
176#else /*M4AD_FORCE_16BITS*/
177    memcpy((void *)pDecodedPCMBuffer->m_dataAddress, (void *)pInputBuffer->m_dataAddress,
178                    pInputBuffer->m_bufferSize );
179#endif /*M4AD_FORCE_16BITS*/
180
181    return M4NO_ERROR;
182}
183
184/**
185 ************************************************************************
186 * @brief   Gets the decoder version
187 * @note    The version is given in a M4_VersionInfo structure
188 *
189 * @param   pValue:     (OUT)       Pointer to the version structure
190 *
191 * @return  M4NO_ERROR              there is no error
192 * @return  M4ERR_PARAMETER         pVersionInfo pointer is null (in DEBUG only)
193 ************************************************************************
194*/
195M4OSA_ERR    M4AD_NULL_getVersion(M4_VersionInfo* pVersionInfo)
196{
197    M4OSA_ERR err = M4NO_ERROR;
198    M4OSA_DEBUG_IF1((pVersionInfo == 0), M4ERR_PARAMETER,
199        "M4AD_NULL_getVersion: invalid pointer pVersionInfo");
200
201    /* Up until now, the null decoder version is not available */
202
203    /* CHANGE_VERSION_HERE */
204    pVersionInfo->m_major        = M4AD_NULL_MAJOR;      /*major version of the component*/
205    pVersionInfo->m_minor        = M4AD_NULL_MINOR;      /*minor version of the component*/
206    pVersionInfo->m_revision    = M4AD_NULL_REVISION;    /*revision version of the component*/
207    pVersionInfo->m_structSize=sizeof(M4_VersionInfo);
208
209    return err;
210}
211
212
213/**
214 ************************************************************************
215 * getInterface function definitions of NXP MP3 decoder
216 ************************************************************************
217*/
218
219/**
220 ************************************************************************
221 * @brief Retrieves the interface implemented by the decoder
222 * @param pDecoderType        : pointer on an M4AD_Type (allocated by the caller)
223 *                              that will be filled with the decoder type supported by
224 *                              this decoder
225 * @param pDecoderInterface   : address of a pointer that will be set to the interface
226 *                              implemented by this decoder. The interface is a structure
227 *                              allocated by the function and must be un-allocated by the
228 *                              caller.
229 *
230 * @return    M4NO_ERROR  if OK
231 * @return    M4ERR_ALLOC if allocation failed
232 ************************************************************************
233*/
234M4OSA_ERR M4AD_NULL_getInterface( M4AD_Type *pDecoderType, M4AD_Interface **pDecoderInterface)
235{
236    *pDecoderInterface = (  M4AD_Interface*)M4OSA_32bitAlignedMalloc( sizeof(M4AD_Interface),
237                            M4DECODER_AUDIO, (M4OSA_Char *)"M4AD_Interface" );
238    if (M4OSA_NULL == *pDecoderInterface)
239    {
240        return M4ERR_ALLOC;
241    }
242
243    *pDecoderType = M4AD_kTypePCM;
244
245    (*pDecoderInterface)->m_pFctCreateAudioDec       = M4AD_NULL_create;
246    (*pDecoderInterface)->m_pFctDestroyAudioDec      = M4AD_NULL_destroy;
247    (*pDecoderInterface)->m_pFctStepAudioDec         = M4AD_NULL_step;
248    (*pDecoderInterface)->m_pFctGetVersionAudioDec   = M4AD_NULL_getVersion;
249    (*pDecoderInterface)->m_pFctStartAudioDec        = M4OSA_NULL;
250    (*pDecoderInterface)->m_pFctResetAudioDec        = M4OSA_NULL;
251    (*pDecoderInterface)->m_pFctSetOptionAudioDec    = M4OSA_NULL;
252    (*pDecoderInterface)->m_pFctGetOptionAudioDec    = M4OSA_NULL;
253
254    return M4NO_ERROR;
255}
256
257