source: svn/newcon3bcm2_21bu/nexus/modules/audio/7552/src/nexus_audio_mixer.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 15.5 KB
Line 
1/***************************************************************************
2*     (c)2004-2011 Broadcom Corporation
3*
4*  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5*  and may only be used, duplicated, modified or distributed pursuant to the terms and
6*  conditions of a separate, written license agreement executed between you and Broadcom
7*  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8*  no license (express or implied), right to use, or waiver of any kind with respect to the
9*  Software, and Broadcom expressly reserves all rights in and to the Software and all
10*  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11*  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12*  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13*
14*  Except as expressly set forth in the Authorized License,
15*
16*  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17*  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18*  and to use this information only in connection with your use of Broadcom integrated circuit products.
19*
20*  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21*  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22*  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23*  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24*  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25*  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26*  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27*  USE OR PERFORMANCE OF THE SOFTWARE.
28*
29*  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30*  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31*  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32*  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33*  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34*  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35*  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36*  ANY LIMITED REMEDY.
37*
38* $brcm_Workfile: nexus_audio_mixer.c $
39* $brcm_Revision: 7 $
40* $brcm_Date: 10/10/11 10:18a $
41*
42* API Description:
43*   API name: AudioMixer
44*    APIs for an audio mixer.  Allows multiple inputs to be connected to outputs.
45*
46* Revision History:
47*
48* $brcm_Log: /nexus/modules/audio/7422/src/nexus_audio_mixer.c $
49*
50* 7   10/10/11 10:18a jgarrett
51* SW7425-1119: Merge to main branch
52*
53* SW7425-1119/3   9/26/11 4:14p jgarrett
54* SW7425-1119: Allowing compressed inputs
55*
56* SW7425-1119/2   8/29/11 6:20p jgarrett
57* SW7425-1119: Adding PrepareToStart in start routine
58*
59* SW7425-1119/1   8/26/11 12:19p jgarrett
60* SW7425-1119: Adding mixer start/stop routines
61*
62* 6   9/15/11 3:24p jgarrett
63* SWDTV-8673: Downgrading debug message
64*
65* 5   6/28/11 10:33a jgarrett
66* SW7422-406: Adding input volume settings for DSP mixers
67*
68* 4   6/5/11 6:57p jgarrett
69* SW7425-406: Initial FW mixer implemenation on APE
70*
71* 3   5/25/11 5:16p jgarrett
72* SW7425-408: Adding BDBG_OBJECT to input/output types and MS11 features
73*
74* 2   4/26/11 11:35a jgarrett
75* SW7425-437: Resolving kernel mode shutdown issues
76*
77* 1   12/17/10 3:56p jgarrett
78* SW7422-146: Adding initial nexus on APE for 7422
79*
80***************************************************************************/
81#include "nexus_audio_module.h"
82#include "nexus_pid_channel.h"
83#include "nexus_timebase.h"    /* Timebase */
84
85BDBG_MODULE(nexus_audio_mixer);
86
87BDBG_OBJECT_ID(NEXUS_AudioMixer);
88typedef struct NEXUS_AudioMixer
89{
90    BDBG_OBJECT(NEXUS_AudioMixer)
91    bool opened;
92    bool started;
93    NEXUS_AudioMixerSettings settings;
94    NEXUS_AudioInputObject connector;
95    BAPE_MixerHandle dspMixer;
96} NEXUS_AudioMixer;
97
98#if NEXUS_NUM_AUDIO_MIXERS
99static NEXUS_AudioMixer g_mixers[NEXUS_NUM_AUDIO_MIXERS];
100
101/***************************************************************************
102Summary:
103    Get default settings for an audio mixer
104See Also:
105    NEXUS_AudioMixer_Open
106 ***************************************************************************/
107void NEXUS_AudioMixer_GetDefaultSettings(
108    NEXUS_AudioMixerSettings *pSettings    /* [out] Default Settings */
109    )
110{
111    BDBG_ASSERT(NULL != pSettings);
112    BKNI_Memset(pSettings, 0, sizeof(NEXUS_AudioMixerSettings));
113}
114
115/***************************************************************************
116Summary:
117    Open an audio mixer
118See Also:
119    NEXUS_AudioMixer_Close
120 ***************************************************************************/
121NEXUS_AudioMixerHandle NEXUS_AudioMixer_Open(
122    const NEXUS_AudioMixerSettings *pSettings
123    )
124{
125    NEXUS_AudioMixer *pMixer=NULL;
126    int i;
127    NEXUS_Error rc=0;
128    NEXUS_AudioMixerSettings defaults;
129
130    if ( NULL == pSettings )
131    {
132        NEXUS_AudioMixer_GetDefaultSettings(&defaults);
133        pSettings = &defaults;
134    }
135
136    for ( i = 0; i < NEXUS_NUM_AUDIO_MIXERS; i++ )
137    {
138        pMixer = &g_mixers[i];
139        if ( !pMixer->opened )
140        {
141            /* Clear structure */
142            BKNI_Memset(pMixer, 0, sizeof(*pMixer));
143            BDBG_OBJECT_SET(pMixer, NEXUS_AudioMixer);
144            pMixer->opened = true;
145            break;
146        }
147    }
148
149    if ( i >= NEXUS_NUM_AUDIO_MIXERS )
150    {
151        BDBG_ERR(("Out of mixers"));
152        rc=BERR_TRACE(BERR_NOT_SUPPORTED);
153        return NULL;
154    }
155
156    pMixer->settings.mixUsingDsp = pSettings->mixUsingDsp;
157    BDBG_MSG(("mixUsingDsp = %u",pMixer->settings.mixUsingDsp));
158
159    /* Setup connector */
160    if ( pSettings->mixUsingDsp )
161    {
162        BAPE_MixerSettings mixerSettings;
163        BAPE_Connector connector;
164
165        NEXUS_AUDIO_INPUT_INIT(&pMixer->connector, NEXUS_AudioInputType_eDspMixer, pMixer);
166        BAPE_Mixer_GetDefaultSettings(&mixerSettings);
167        mixerSettings.type = BAPE_MixerType_eDsp;
168        rc = BAPE_Mixer_Create(NEXUS_AUDIO_DEVICE_HANDLE, &mixerSettings, &pMixer->dspMixer);
169        if ( rc )
170        {
171            rc=BERR_TRACE(rc);
172            return NULL;
173        }
174        BAPE_Mixer_GetConnector(pMixer->dspMixer, &connector);
175        pMixer->connector.port = (uint32_t)connector;
176    }
177    else
178    {
179        NEXUS_AUDIO_INPUT_INIT(&pMixer->connector, NEXUS_AudioInputType_eMixer, pMixer);
180    }
181    pMixer->connector.format = NEXUS_AudioInputFormat_eNone; /* Determined by inputs */
182
183    /* Set Settings */
184    NEXUS_AudioMixer_SetSettings(pMixer, pSettings);        /* Handles NULL for defaults */
185
186    /* Success */
187    return pMixer;
188}
189
190/***************************************************************************
191Summary:
192    Close an audio mixer
193See Also:
194    NEXUS_AudioMixer_Open
195 ***************************************************************************/
196void NEXUS_AudioMixer_Close(
197    NEXUS_AudioMixerHandle handle
198    )
199{
200    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
201
202    NEXUS_AudioInput_Shutdown(&handle->connector);
203
204    if ( handle->dspMixer )
205    {
206        BAPE_Mixer_Destroy(handle->dspMixer);
207    }
208
209    /* Done */
210    BKNI_Memset(handle, 0, sizeof(NEXUS_AudioMixer));
211}
212
213/***************************************************************************
214Summary:
215    Get current settings for an audio mixer
216See Also:
217    NEXUS_AudioMixer_SetSettings
218 ***************************************************************************/
219void NEXUS_AudioMixer_GetSettings(
220    NEXUS_AudioMixerHandle handle,
221    NEXUS_AudioMixerSettings *pSettings      /* [out] Mixer Settings */
222    )
223{
224    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
225    BDBG_ASSERT(NULL != pSettings);
226
227    *pSettings = handle->settings;
228}
229
230/***************************************************************************
231Summary:
232    Set settings of an audio mixer
233See Also:
234    NEXUS_AudioMixer_SetSettings
235 ***************************************************************************/
236NEXUS_Error NEXUS_AudioMixer_SetSettings(
237    NEXUS_AudioMixerHandle handle,
238    const NEXUS_AudioMixerSettings *pSettings    /* [out] Mixer Settings */
239    )
240{
241    NEXUS_AudioInput oldMaster, newMaster;
242    NEXUS_Error errCode;
243
244    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
245    BDBG_ASSERT(NULL != pSettings);
246
247    if ( handle->settings.mixUsingDsp != pSettings->mixUsingDsp )
248    {
249        BDBG_ERR(("mixUsingDsp can only be set when a mixer is opened.  It cannot be changed on-the-fly."));
250        BDBG_ASSERT(0);
251        return BERR_TRACE(BERR_NOT_SUPPORTED);
252    }
253    oldMaster = handle->settings.master;
254    newMaster = pSettings->master;
255
256    handle->settings = *pSettings;
257
258    if ( oldMaster != newMaster )
259    {
260        if ( NULL != newMaster )
261        {
262            errCode = NEXUS_AudioMixer_RemoveInput(handle, newMaster);
263            if ( errCode )
264            {
265                BDBG_ERR(("Master input %#x is not connected to mixer %#x", pSettings->master, handle));
266                handle->settings.master = NULL;
267                return BERR_TRACE(BERR_NOT_SUPPORTED);
268            }
269            errCode = NEXUS_AudioMixer_AddInput(handle, newMaster);
270            if ( errCode )
271            {
272                handle->settings.master = NULL;
273                return BERR_TRACE(BERR_NOT_SUPPORTED);
274            }
275        }
276    }
277
278    /* Success */
279    return BERR_SUCCESS;
280}
281
282NEXUS_Error NEXUS_AudioMixer_Start(
283    NEXUS_AudioMixerHandle handle
284    )
285{
286    BERR_Code errCode;
287    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
288
289    if ( handle->started )
290    {
291        BDBG_ERR(("Already started."));
292    }
293   
294    if ( handle->settings.mixUsingDsp )
295    {
296        errCode = NEXUS_AudioInput_P_PrepareToStart(&handle->connector);
297        if ( errCode )
298        {
299            return BERR_TRACE(errCode);
300        }
301
302        errCode = BAPE_Mixer_Start(handle->dspMixer);
303        if ( errCode )
304        {
305            return BERR_TRACE(errCode);
306        }
307   
308        handle->started = true;   
309        return BERR_SUCCESS;
310    }
311    else
312    {
313        return BERR_TRACE(BERR_NOT_SUPPORTED);
314    }       
315}
316
317void NEXUS_AudioMixer_Stop(
318    NEXUS_AudioMixerHandle handle
319    )
320{
321    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
322   
323    if ( false == handle->started )
324    {
325        return;
326    }
327   
328    if ( handle->settings.mixUsingDsp )
329    {
330        BAPE_Mixer_Stop(handle->dspMixer);
331        handle->started = false;
332    }
333    else
334    {
335        (void)BERR_TRACE(BERR_NOT_SUPPORTED);
336    }           
337}
338   
339/***************************************************************************
340Summary:
341    Add an audio input to a mixer
342See Also:
343    NEXUS_AudioMixer_RemoveInput
344 ***************************************************************************/
345NEXUS_Error NEXUS_AudioMixer_AddInput(
346    NEXUS_AudioMixerHandle handle,
347    NEXUS_AudioInput input
348    )
349{
350    BERR_Code errCode;
351
352    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
353    BDBG_ASSERT(NULL != input);
354
355    /* Check if new input is already running */
356    if ( NEXUS_AudioInput_P_IsRunning(input) )
357    {
358        BDBG_ERR(("Input %p is running.  Please stop first.", input));
359        return BERR_TRACE(BERR_NOT_SUPPORTED);
360    }
361
362    /* Check if I'm running */
363    if ( NEXUS_AudioInput_P_IsRunning(&handle->connector) || handle->started )
364    {
365        BDBG_ERR(("Mixer %p is running.  Stop all inputs first.", handle));
366        return BERR_TRACE(BERR_NOT_SUPPORTED);
367    }
368
369    if ( handle->settings.mixUsingDsp )
370    {
371        BAPE_MixerAddInputSettings addInputSettings;
372        BAPE_MixerInputVolume inputVolume;
373        bool master = (input == handle->settings.master)?true:false;
374
375        BAPE_Mixer_GetDefaultAddInputSettings(&addInputSettings);
376        addInputSettings.sampleRateMaster = master;
377        errCode = BAPE_Mixer_AddInput(handle->dspMixer, (BAPE_Connector)input->port, &addInputSettings);
378        if ( errCode )
379        {
380            return BERR_TRACE(errCode);
381        }
382        /* Match input volume in mixer */
383        NEXUS_AudioInput_P_GetVolume(input, &inputVolume);
384        errCode = BAPE_Mixer_SetInputVolume(handle->dspMixer, (BAPE_Connector)input->port, &inputVolume);
385        if ( errCode )
386        {
387            return BERR_TRACE(errCode);
388        }
389    }
390
391    /* Connect at input node */
392    errCode = NEXUS_AudioInput_P_AddInput(&handle->connector, input);
393    if ( errCode )
394    {
395        if ( handle->settings.mixUsingDsp )
396        {
397            BAPE_Mixer_RemoveInput(handle->dspMixer, (BAPE_Connector)input->port);
398        }
399        return BERR_TRACE(errCode);
400    }
401
402    return BERR_SUCCESS;
403}
404
405/***************************************************************************
406Summary:
407    Remove all audio inputs from a mixer
408See Also:
409    NEXUS_AudioMixer_RemoveInput
410 ***************************************************************************/
411NEXUS_Error NEXUS_AudioMixer_RemoveAllInputs(
412    NEXUS_AudioMixerHandle handle
413    )
414{
415    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
416
417    /* Check if I'm running */
418    if ( NEXUS_AudioInput_P_IsRunning(&handle->connector) || handle->started )
419    {
420        BDBG_ERR(("Mixer %p is running.  Stop all inputs first.", handle));
421        return BERR_TRACE(BERR_NOT_SUPPORTED);
422    }
423
424    /* Connect at input node */
425    return NEXUS_AudioInput_P_RemoveAllInputs(&handle->connector);
426}
427
428/***************************************************************************
429Summary:
430    Remove an audio input from a mixer
431See Also:
432    NEXUS_AudioMixer_AddInput
433 ***************************************************************************/
434NEXUS_Error NEXUS_AudioMixer_RemoveInput(
435    NEXUS_AudioMixerHandle handle,
436    NEXUS_AudioInput input
437    )
438{
439    BDBG_OBJECT_ASSERT(handle, NEXUS_AudioMixer);
440    BDBG_ASSERT(NULL != input);
441
442    /* Check if I'm running */
443    if ( NEXUS_AudioInput_P_IsRunning(&handle->connector) || handle->started )
444    {
445        BDBG_ERR(("Mixer %p is running.  Stop all inputs first.", handle));
446        return BERR_TRACE(BERR_NOT_SUPPORTED);
447    }
448
449    /* Make sure this input is actually connected to this mixer */
450    if ( !NEXUS_AudioInput_P_IsConnected(&handle->connector, input) )
451    {
452        BDBG_ERR(("Input %p is not connected to mixer %p", input, handle));
453        return BERR_TRACE(BERR_INVALID_PARAMETER);
454    }
455
456    if ( handle->settings.mixUsingDsp )
457    {
458        (void)BAPE_Mixer_RemoveInput(handle->dspMixer, (BAPE_Connector)input->port);
459    }
460
461    /* Remove Input */
462    return NEXUS_AudioInput_P_RemoveInput(&handle->connector, input);
463}
464
465/***************************************************************************
466Summary:
467Get the audio input connector for connection to outputs or post-processing
468***************************************************************************/
469NEXUS_AudioInput NEXUS_AudioMixer_GetConnector(
470    NEXUS_AudioMixerHandle mixer
471    )
472{
473    BDBG_OBJECT_ASSERT(mixer, NEXUS_AudioMixer);
474    return &mixer->connector;
475}
476
477/***************************************************************************
478Summary:
479    Propagate mixer input volume into a mixer object in nexus
480 ***************************************************************************/
481NEXUS_Error NEXUS_AudioMixer_P_SetInputVolume(
482    NEXUS_AudioMixerHandle handle, 
483    NEXUS_AudioInput input,
484    const BAPE_MixerInputVolume *pInputVolume
485    )
486{
487    if ( handle->dspMixer )
488    {
489        BERR_Code errCode;
490
491        errCode = BAPE_Mixer_SetInputVolume(handle->dspMixer, (BAPE_Connector)input->port, pInputVolume);
492        if ( errCode )
493        {
494            return BERR_TRACE(errCode);
495        }
496    }
497
498    return BERR_SUCCESS;
499}
500
501#endif /* #if NEXUS_NUM_AUDIO_MIXERS */
502
Note: See TracBrowser for help on using the repository browser.