IVolume.c revision 979a3f8743646af9999a89dff9e13b972b7efd87
10b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/*
20b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
30b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
40b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
50b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * you may not use this file except in compliance with the License.
60b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * You may obtain a copy of the License at
70b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
80b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
90b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Unless required by applicable law or agreed to in writing, software
110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * See the License for the specific language governing permissions and
140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * limitations under the License.
150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten */
160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* Volume implementation */
180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
19979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#include "sles_allinclusive.h"
20979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten
21979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#ifdef USE_ANDROID
22979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#include "sles_to_android_ext.h"
23979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#endif
240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
250b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_SetVolumeLevel(SLVolumeItf self, SLmillibel level)
260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#if 0
280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // some compilers allow a wider int type to be passed as a parameter,
290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // but that will be truncated during the field assignment
300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (!((SL_MILLIBEL_MIN <= level) && (SL_MILLIBEL_MAX >= level)))
310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif
33b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi#ifdef USE_ANDROID
34b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    if (!((SL_MILLIBEL_MIN <= level) && (ANDROID_SL_MILLIBEL_MAX >= level)))
35b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        return SL_RESULT_PARAMETER_INVALID;
36b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi#endif
37b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi
380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mLevel = level;
41b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    if(this->mMute == SL_BOOLEAN_FALSE) {
426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
43b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        // FIXME poke lock correct?
44b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        switch(this->mThis->mClass->mObjectID) {
456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        case SL_OBJECTID_AUDIOPLAYER:
466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            sles_to_android_audioPlayerVolumeUpdate(this);
476a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            break;
486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        case SL_OBJECTID_OUTPUTMIX:
496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // FIXME mute/unmute all players attached to this outputmix
506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            fprintf(stderr, "FIXME: IVolume_SetVolumeLevel on an SL_OBJECTID_OUTPUTMIX to be implemented\n");
516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            break;
526a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        default:
536a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            break;
54b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        }
556a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
56b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    }
570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
600b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
610b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_GetVolumeLevel(SLVolumeItf self, SLmillibel *pLevel)
620b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pLevel)
640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillibel level = this->mLevel;
680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pLevel = level;
700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
730b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_GetMaxVolumeLevel(SLVolumeItf self,
740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillibel *pMaxLevel)
750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMaxLevel)
770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMaxLevel = SL_MILLIBEL_MAX;
79b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi#ifdef USE_ANDROID
80b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    *pMaxLevel = ANDROID_SL_MILLIBEL_MAX;
81b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi#endif
820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
850b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_SetMute(SLVolumeItf self, SLboolean mute)
860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMute = mute;
90b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    if(this->mMute == SL_BOOLEAN_FALSE) {
91b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        // when unmuting, reapply volume
92b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi        IVolume_SetVolumeLevel(self, this->mLevel);
93b6e3c1093dfbdec29e620e85d0d81cc39395a45fJean-Michel Trivi    }
946a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME poke lock correct?
966a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    switch(this->mThis->mClass->mObjectID) {
976a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        case SL_OBJECTID_AUDIOPLAYER:
986a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            sles_to_android_audioPlayerSetMute(this, mute);
996a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            break;
1006a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        case SL_OBJECTID_OUTPUTMIX:
1016a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            // FIXME mute/unmute all players attached to this outputmix
1026a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            fprintf(stderr, "FIXME: IVolume_SetMute on an SL_OBJECTID_OUTPUTMIX to be implemented\n");
1036a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            break;
1046a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        default:
1056a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi            break;
1066a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1076a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1120b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_GetMute(SLVolumeItf self, SLboolean *pMute)
1130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMute)
1150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
1170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
1180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLboolean mute = this->mMute;
1190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
1200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMute = mute;
1210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1240b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_EnableStereoPosition(SLVolumeItf self, SLboolean enable)
1250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
1270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mEnableStereoPosition = enable;
1296a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
1306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME poke lock correct?
1316a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
1326a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        sles_to_android_audioPlayerVolumeUpdate(this);
1336a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1346a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1390b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_IsEnabledStereoPosition(SLVolumeItf self,
1400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLboolean *pEnable)
1410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pEnable)
1430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
1450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
1460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLboolean enable = this->mEnableStereoPosition;
1470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
1480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pEnable = enable;
1490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1520b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_SetStereoPosition(SLVolumeItf self,
1530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLpermille stereoPosition)
1540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (!((-1000 <= stereoPosition) && (1000 >= stereoPosition)))
1560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
1580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mStereoPosition = stereoPosition;
1606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
1616a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    // FIXME poke lock correct?
1626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    if (this->mThis->mClass->mObjectID == SL_OBJECTID_AUDIOPLAYER) {
1636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        sles_to_android_audioPlayerVolumeUpdate(this);
1646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1700b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IVolume_GetStereoPosition(SLVolumeItf self,
1710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLpermille *pStereoPosition)
1720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1730b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pStereoPosition)
1740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
1760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
1770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLpermille stereoPosition = this->mStereoPosition;
1780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
1790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pStereoPosition = stereoPosition;
1800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1830b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLVolumeItf_ IVolume_Itf = {
1840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_SetVolumeLevel,
1850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_GetVolumeLevel,
1860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_GetMaxVolumeLevel,
1870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_SetMute,
1880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_GetMute,
1890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_EnableStereoPosition,
1900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_IsEnabledStereoPosition,
1910b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_SetStereoPosition,
1920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume_GetStereoPosition
1930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
1940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1950b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IVolume_init(void *self)
1960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IVolume *this = (IVolume *) self;
1980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mItf = &IVolume_Itf;
1990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifndef NDEBUG
2000b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mLevel = 0;
2010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMute = SL_BOOLEAN_FALSE;
2020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mEnableStereoPosition = SL_BOOLEAN_FALSE;
2030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mStereoPosition = 0;
2040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif
2056a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
2066a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    this->mAmplFromVolLevel = 1.0f;
2076a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    this->mAmplFromStereoPos[0] = 1.0f;
2086a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    this->mAmplFromStereoPos[1] = 1.0f;
2096a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    this->mChannelMutes = 0;
2106a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    this->mChannelSolos = 0;
2116a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
2120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
213