1193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi/*
2193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * Copyright (C) 2010 The Android Open Source Project
3193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi *
4193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
5193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * you may not use this file except in compliance with the License.
6193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * You may obtain a copy of the License at
7193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi *
8193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
9193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi *
10193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
12193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * See the License for the specific language governing permissions and
14193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi * limitations under the License.
15193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi */
16193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
1710ee2bc6119445f4339ecef998c40c9cc95057cdGlenn Kasten/** \file sles_allinclusive.h Everything including the kitchen sink */
1810ee2bc6119445f4339ecef998c40c9cc95057cdGlenn Kasten
19a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES.h>
20a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <OMXAL/OpenMAXAL.h>
2151cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#ifdef ANDROID
22a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <SLES/OpenSLES_Android.h>
23a6c5e52ded343b557152156c33d33a10d29bf6f1Glenn Kasten#include <OMXAL/OpenMAXAL_Android.h>
2451cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#endif
25193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <stddef.h> // offsetof
26193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <stdlib.h> // malloc
27193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <string.h> // memcmp
28146a529e3b2c610be8517f99ea73e6b79e8af459Carl Shapiro#include <strings.h>
29193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <stdio.h>  // debugging
30193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <assert.h> // debugging
31193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <pthread.h>
32d8d51367a2ad6005786b5ac904575cc7a4d9b728Glenn Kasten#include <unistd.h> // usleep
33437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten#include <errno.h>
34193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
359c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#ifndef __cplusplus
369c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kastentypedef int bool;
379c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#ifndef false
389c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#define false 0
399c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#endif
409c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#ifndef true
419c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#define true 1
429c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#endif
439c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten#endif
449c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten
4551cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten// The OpenSLES.h definitions of SL_PROFILES_... have casts, so are unusable by preprocessor
4651cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#define USE_PROFILES_PHONE    0x1   // == SL_PROFILES_PHONE
4751cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#define USE_PROFILES_MUSIC    0x2   // == SL_PROFILES_MUSIC
4851cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#define USE_PROFILES_GAME     0x4   // == SL_PROFILES_GAME
4951cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten// Pseudo profiles, used to decide whether to include code for incomplete or untested features
5051cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten// Features that are not in union of all profiles: audio recorder, LED, Vibra
5151cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#define USE_PROFILES_OPTIONAL 0x8
5251cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten// Features that are in the intersection of all profiles:
5351cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten// object priorities, preemption, loss of control, device configuration
5451cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#define USE_PROFILES_BASE     0x10
5551cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten
56193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include "MPH.h"
57193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include "MPH_to.h"
5882b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten#include "devices.h"
59439af19ad7484b0472080e8eb0cd8462a17b0286Glenn Kasten#include "ut/OpenSLESUT.h"
60437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten#include "ThreadPool.h"
61193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
623be625f40588941aa23e35fed5cb693ddc9718daGlenn Kastentypedef struct CEngine_struct CEngine;
634c0d2128c7c0a8b40803026d92083b6affc417d2Glenn Kastentypedef struct CAudioPlayer_struct CAudioPlayer;
64bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Trivitypedef struct CAudioRecorder_struct CAudioRecorder;
65ffeb2e16c2886eefa88d6eaf4c7be78c2eced82bGlenn Kastentypedef struct C3DGroup_struct C3DGroup;
6615f9f5e609265dff9d6036af38bea084c42a702aGlenn Kastentypedef struct COutputMix_struct COutputMix;
674c0d2128c7c0a8b40803026d92083b6affc417d2Glenn Kasten
68193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#ifdef USE_SNDFILE
69193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <sndfile.h>
70439af19ad7484b0472080e8eb0cd8462a17b0286Glenn Kasten#include "desktop/SLSndFile.h"
71193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#endif // USE_SNDFILE
72193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
73193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#ifdef USE_SDL
74193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include <SDL/SDL_audio.h>
75193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#endif // USE_SDL
76193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
7727a8821eb36f002b81f368a0049f511cfa465d16Jean-Michel Trivi#define STEREO_CHANNELS 2
7827a8821eb36f002b81f368a0049f511cfa465d16Jean-Michel Trivi
79463a7641944e4a3613f5d76aa8450070ef56b9ffGlenn Kasten/**
80463a7641944e4a3613f5d76aa8450070ef56b9ffGlenn Kasten * Constants to define unknown property values
81463a7641944e4a3613f5d76aa8450070ef56b9ffGlenn Kasten */
82463a7641944e4a3613f5d76aa8450070ef56b9ffGlenn Kasten#define UNKNOWN_NUMCHANNELS 0
83463a7641944e4a3613f5d76aa8450070ef56b9ffGlenn Kasten#define UNKNOWN_SAMPLERATE  0
84463a7641944e4a3613f5d76aa8450070ef56b9ffGlenn Kasten#define UNKNOWN_CHANNELMASK 0
85463a7641944e4a3613f5d76aa8450070ef56b9ffGlenn Kasten
869db8335361c67c4ed877f68218835df96ce43a4bJean-Michel Trivi#ifdef ANDROID
87f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten#include <utils/Log.h>
885bd7bea2bbc5133d26cdcd8b95d3452bd0116680Jean-Michel Trivi#include <utils/KeyedVector.h>
89193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include "media/AudioSystem.h"
90bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Trivi#include "media/mediarecorder.h"
91bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Trivi#include "media/AudioRecord.h"
92193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include "media/AudioTrack.h"
93193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#include "media/mediaplayer.h"
940263d22efc4ad9420b367ec61b5a1d1ec72cebb9Jean-Michel Trivi#include <utils/String8.h>
958a307c7272108766eebabc7fa7044d7510d65f77Jean-Michel Trivi#define ANDROID_SL_MILLIBEL_MAX 0
96439af19ad7484b0472080e8eb0cd8462a17b0286Glenn Kasten#include "android/android_sles_conversions.h"
97439af19ad7484b0472080e8eb0cd8462a17b0286Glenn Kasten#include "android/android_defs.h"
98ff9f51f17b6c00beaa51698e22873a979c7b3ff6Glenn Kasten#endif
9915f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten
100193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#ifdef USE_OUTPUTMIXEXT
101439af19ad7484b0472080e8eb0cd8462a17b0286Glenn Kasten#include "desktop/OutputMixExt.h"
102193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#endif
103193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
10403716fc64636a68ba59881508e80550b948f0f40Glenn Kasten#include "sllog.h"
10503716fc64636a68ba59881508e80550b948f0f40Glenn Kasten
106b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastentypedef enum {
107b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kasten    predestroy_error,   // Application should not be calling destroy now
108b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kasten    predestroy_ok,      // OK to destroy object now
109b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kasten    predestroy_again    // Application did nothing wrong, but should destroy again to be effective
110b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kasten} predestroy_t;
111b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kasten
112193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi// Hook functions
113193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
114193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivitypedef void (*VoidHook)(void *self);
1152a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten//typedef SLresult (*ResultHook)(void *self);
1168a47ad52488855f50b95da649744dde3a254698bJean-Michel Trivitypedef SLresult (*AsyncHook)(void *self, SLboolean async);
1174f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kastentypedef bool (*BoolHook)(void *self);
118b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastentypedef predestroy_t (*PreDestroyHook)(void *self);
1194cf440cd9f6106db00571345af7aa02529c9a10aJean-Michel Trivi
120bd2fc031926582ee8b0df40673c66dfa4cc45a61Glenn Kasten// Describes how an interface is related to a given class, used in iid_vtable::mInterface
121193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
122bd2fc031926582ee8b0df40673c66dfa4cc45a61Glenn Kasten#define INTERFACE_IMPLICIT            0 // no need for application to request prior to GetInterface
123bd2fc031926582ee8b0df40673c66dfa4cc45a61Glenn Kasten#define INTERFACE_EXPLICIT            1 // must be requested explicitly during object creation
124bd2fc031926582ee8b0df40673c66dfa4cc45a61Glenn Kasten#define INTERFACE_DYNAMIC             2 // can be requested after object creation
125bd2fc031926582ee8b0df40673c66dfa4cc45a61Glenn Kasten#define INTERFACE_UNAVAILABLE         3 // this interface is not available on objects of this class
1269a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten#define INTERFACE_IMPLICIT_PREREALIZE 4 // implicit, and can call GetInterface before Realize
1279a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten#define INTERFACE_EXPLICIT_PREREALIZE 5 // explicit, and can call GetInterface before Realize
1289a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten// 6 and 7 are reserved for the meaningless DYNAMIC_PREREALIZE and UNAVAILABLE_PREREALIZE
12904bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten// note that INTERFACE_OPTIONAL is always re-mapped to one of the above
1309a889c24ace7bbc9659e1531d7a61dc43452d7c0Glenn Kasten#define INTERFACE_PREREALIZE          4 // bit-mask to test for calling GetInterface before Realize
13104bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten
13204bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten// Profile-specific interfaces
13304bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten
13451cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#if USE_PROFILES & USE_PROFILES_BASE
13504bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_IMPLICIT_BASE       INTERFACE_IMPLICIT
13604bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_BASE       INTERFACE_EXPLICIT
13704bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#else
13804bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_IMPLICIT_BASE       INTERFACE_UNAVAILABLE
13904bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_BASE       INTERFACE_UNAVAILABLE
14004bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#endif
14104bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten
14251cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#if USE_PROFILES & USE_PROFILES_GAME
14304bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_GAME        INTERFACE_DYNAMIC
14404bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_GAME       INTERFACE_EXPLICIT
14504bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#else
14604bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_GAME        INTERFACE_OPTIONAL
14704bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_GAME       INTERFACE_OPTIONAL
14804bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#endif
14904bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten
15051cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#if USE_PROFILES & USE_PROFILES_MUSIC
15104bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_MUSIC       INTERFACE_DYNAMIC
15204bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#else
15304bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_MUSIC       INTERFACE_OPTIONAL
15404bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#endif
15504bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten
15651cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
15704bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_GAME_MUSIC  INTERFACE_DYNAMIC
15804bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_GAME_MUSIC INTERFACE_EXPLICIT
15904bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#else
16004bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_GAME_MUSIC  INTERFACE_OPTIONAL
16104bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_GAME_MUSIC INTERFACE_OPTIONAL
16204bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#endif
16304bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten
16451cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
16504bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_GAME_PHONE INTERFACE_EXPLICIT
16604bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#else
16704bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_EXPLICIT_GAME_PHONE INTERFACE_OPTIONAL
16804bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#endif
16904bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten
17051cb31b09f6af53402b3fbe7e9de29badc1155a2Glenn Kasten#if USE_PROFILES & USE_PROFILES_OPTIONAL
17104bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_OPTIONAL            INTERFACE_EXPLICIT
17204bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_OPTIONAL    INTERFACE_DYNAMIC
173f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten#else
17404bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_OPTIONAL            INTERFACE_UNAVAILABLE
17504bd7e37c043835a177bedc7cc7520c30d32951aGlenn Kasten#define INTERFACE_DYNAMIC_OPTIONAL    INTERFACE_UNAVAILABLE
176f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten#endif
177f51f5c6ec99ebc8f2c833a68f232bc1c874a7f2fGlenn Kasten
178bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten// Describes how an interface is related to a given object
179bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten
1802a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_UNINITIALIZED 0  ///< not available
1812a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_INITIALIZED   1  ///< not requested at object creation time
1822a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_EXPOSED       2  ///< requested at object creation time
1832a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_ADDING_1      3  ///< part 1 of asynchronous AddInterface, pending
1842a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_ADDING_2      4  ///< synchronous AddInterface, or part 2 of asynchronous
1852a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_ADDED         5  ///< AddInterface has completed
1862a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_REMOVING      6  ///< unlocked phase of (synchronous) RemoveInterface
1872a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_SUSPENDING    7  ///< suspend in progress
1882a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_SUSPENDED     8  ///< suspend has completed
1892a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_RESUMING_1    9  ///< part 1 of asynchronous ResumeInterface, pending
1902a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_RESUMING_2   10  ///< synchronous ResumeInterface, or part 2 of asynchronous
1912a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_ADDING_1A    11  ///< part 1 of asynchronous AddInterface, aborted
1922a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten#define INTERFACE_RESUMING_1A  12  ///< part 1 of asynchronous ResumeInterface, aborted
193bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten
194de8654b40c7701ea213c157448cbb96c29522e39Jean-Michel Trivi
195193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi// Maps an interface ID to its offset within the class that exposes it
196193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
197193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivistruct iid_vtable {
1981a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten    unsigned char mMPH;         // primary MPH for this interface, does not include any aliases
1991a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten    unsigned char mInterface;   // relationship of interface to this class
200193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    /*size_t*/ unsigned short mOffset;
201193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi};
202193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
203193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi// Per-class const data shared by all instances of the same class
204193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
205903042393ae2c797ffb6025979b8395a2cd1ff97Glenn Kastentypedef struct {
2061a6bb4f8e738c9387dc9629db294ea5de618a53cGlenn Kasten    const struct iid_vtable *mInterfaces;   // maps interface index to info about that interface
207bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten    SLuint32 mInterfaceCount;  // number of possible interfaces
208193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    const signed char *mMPH_to_index;
209ee35e132113602e20012829377d16f0572c61195Glenn Kasten    const char * const mName;
210193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    size_t mSize;
2110ed2690aa6d6a41a653713e7a961c1a7d0cd6cfbGlenn Kasten    // OpenSL ES and OpenMAX AL object IDs come from different ranges, and some objects such as
2120ed2690aa6d6a41a653713e7a961c1a7d0cd6cfbGlenn Kasten    // Engine, Output Mix, LED, and Vibra belong to both APIs, so we keep both object IDs
2130ed2690aa6d6a41a653713e7a961c1a7d0cd6cfbGlenn Kasten    SLuint16 mSLObjectID;   // OpenSL ES object ID
2140ed2690aa6d6a41a653713e7a961c1a7d0cd6cfbGlenn Kasten    XAuint16 mXAObjectID;   // OpenMAX AL object ID
215bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten    // hooks
2163f031aeec70082817e78f478af796e8f5f3d4390Glenn Kasten    AsyncHook mRealize;     // called with mutex locked; can temporarily unlock mutex (for async)
2173f031aeec70082817e78f478af796e8f5f3d4390Glenn Kasten    AsyncHook mResume;      // called with mutex locked; can temporarily unlock mutex (for async)
2183f031aeec70082817e78f478af796e8f5f3d4390Glenn Kasten    VoidHook mDestroy;      // called with mutex locked and must keep mutex locked throughout
2193f031aeec70082817e78f478af796e8f5f3d4390Glenn Kasten    PreDestroyHook mPreDestroy; // called with mutex locked; can temporarily unlock mutex (for wait)
220903042393ae2c797ffb6025979b8395a2cd1ff97Glenn Kasten} ClassTable;
221193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
222193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi// BufferHeader describes each element of a BufferQueue, other than the data
223437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastentypedef struct {
224193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    const void *mBuffer;
225193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    SLuint32 mSize;
226437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten} BufferHeader;
227193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
2285b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi#ifdef ANDROID
2295b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi// Holds information about all commands that can be passed alongside an MPEG-2 TS buffer
2305b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi// Is used with buffers of type kAndroidBufferTypeMpeg2Ts
2315b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivitypedef struct {
2325b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi    SLuint32 mTsCmdCode;
23330ebe675beff91283cc72d4ee5e94e56ab7e107fJean-Michel Trivi    SLAuint64 mPts;
2345b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi} Mpeg2TsCommands;
2355b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi
236333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi// Holds information about all commands that can be passed alongside an AAC ADTS buffer
237333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi// Is used with buffers of type kAndroidBufferTypeAacadts
238333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivitypedef struct {
239333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi    SLuint32 mAdtsCmdCode;
240333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi} AdtsCommands;
241333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi
2425b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi// Union of the different structures to hold items stored in an AdvancedBufferHeader
2435b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi//   when an item comes from an AndroidBufferQueue as the data source, it's a command
2445b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi//   when an item is output to an AndroidBufferQueue as the data sink, it's a message (or metadata)
2455b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivitypedef union {
2465b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi    Mpeg2TsCommands mTsCmdData;
247333c2341445e9f161ff022a4b7d5f69e9e149b60Jean-Michel Trivi    AdtsCommands    mAdtsCmdData;
2485b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi} AdvancedBufferItems;
2495b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi
250f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi// AdvancedBufferHeader describes each element of an AndroidBufferQueue, other than the data
251f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi//  and associated messages
252f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivitypedef struct {
253f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    const void *mDataBuffer;
254f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    SLuint32 mDataSize;
255f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi    SLuint32 mDataSizeConsumed;
2565b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi    AdvancedBufferItems mItems;
257fcc996296bdbf6c3949ad4312991fdde4ae2e157Jean-Michel Trivi    const void *mBufferContext;
2584756e5726b53c2b4d7fae8b66b5596afd7fcf309Jean-Michel Trivi    SLuint32 mBufferState;
259f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi} AdvancedBufferHeader;
2605b21a0626e173d407aa3835e5cffcaa9b582016dJean-Michel Trivi#endif
261f65b260193e5ca669ec4479a7e1c4517e18cc6b0Jean-Michel Trivi
262193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#ifdef USE_SNDFILE
263193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
264ffeb2e16c2886eefa88d6eaf4c7be78c2eced82bGlenn Kasten#define SndFile_BUFSIZE 512     // in 16-bit samples
265ffeb2e16c2886eefa88d6eaf4c7be78c2eced82bGlenn Kasten#define SndFile_NUMBUFS 2
266ffeb2e16c2886eefa88d6eaf4c7be78c2eced82bGlenn Kasten
267193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivistruct SndFile {
268193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    // save URI also?
269193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    SLchar *mPathname;
270193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi    SNDFILE *mSNDFILE;
27123c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten    SF_INFO mSfInfo;
27215f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten    pthread_mutex_t mMutex; // protects mSNDFILE only
27315f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten    SLboolean mEOF;         // sf_read returned zero sample frames
27466f75c45c9aea410b1f913d76995661e72571b67Glenn Kasten    SLuint32 mWhich;        // which buffer to use next
275ffeb2e16c2886eefa88d6eaf4c7be78c2eced82bGlenn Kasten    short mBuffer[SndFile_BUFSIZE * SndFile_NUMBUFS];
276193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi};
277193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
278193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi#endif // USE_SNDFILE
279193ed0e1816bfbdf71325b6a617aa2636d8fcb21Jean-Michel Trivi
28034a2d76d36b5b50a5792963b14ab2ce3bfed1086Glenn Kasten#include "data.h"
28134a2d76d36b5b50a5792963b14ab2ce3bfed1086Glenn Kasten#include "itfstruct.h"
28234a2d76d36b5b50a5792963b14ab2ce3bfed1086Glenn Kasten#include "classes.h"
28382b1fcaca1b9c870c1a7978f0986fdad2fe7d06eGlenn Kasten
28423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstruct MPH_init {
2852a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten    VoidHook mInit;     // called first to initialize the interface, right after object is allocated
2862a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten    // Each interface is initialized regardless whether it is exposed to application.
2872a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten    VoidHook mResume;   // called to resume interface after suspension, not currently used
2882a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten    VoidHook mDeinit;   // called last when object is about to be destroyed
2892a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten    BoolHook mExpose;   // called after initialization, only if interface is exposed to application
290d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kasten    VoidHook mRemove;   // called by DynamicInterfaceManager::RemoveInterface, and prior to mDeinit
2912a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten    // will need a suspend hook when suspend is implemented
29223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten};
29323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
29423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenextern /*static*/ int IID_to_MPH(const SLInterfaceID iid);
29523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenextern /*static*/ const struct MPH_init MPH_init_table[MPH_MAX];
29650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kastenextern SLresult checkInterfaces(const ClassTable *clazz,
297492fab3a4ef52dcf39e7e7269ea393e4ea93f3d8Glenn Kasten    SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
2984d09a0398246d352006db429fca6ea0d3cc17d65Glenn Kasten    const SLboolean *pInterfaceRequired, unsigned *pExposedMask, unsigned *pRequiredMask);
29950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kastenextern IObject *construct(const ClassTable *clazz,
300492fab3a4ef52dcf39e7e7269ea393e4ea93f3d8Glenn Kasten    unsigned exposedMask, SLEngineItf engine);
301492fab3a4ef52dcf39e7e7269ea393e4ea93f3d8Glenn Kastenextern const ClassTable *objectIDtoClass(SLuint32 objectID);
302492fab3a4ef52dcf39e7e7269ea393e4ea93f3d8Glenn Kastenextern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
303188a1af5a1d2e2c339cded3dc5bbd99c2fd89fefGlenn Kastenextern SLuint32 IObjectToObjectID(IObject *object);
30450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kastenextern void IObject_Publish(IObject *thiz);
30531df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kastenextern void IObject_Destroy(SLObjectItf self);
306188a1af5a1d2e2c339cded3dc5bbd99c2fd89fefGlenn Kasten
30732a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten// Map an interface to it's "object ID" (which is really a class ID).
30832a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten// Note: this operation is undefined on IObject, as it lacks an mThis.
30932a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten// If you have an IObject, then use IObjectToObjectID directly.
310188a1af5a1d2e2c339cded3dc5bbd99c2fd89fefGlenn Kasten
31150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten#define InterfaceToObjectID(thiz) IObjectToObjectID((thiz)->mThis)
312f6f90fc5202248e2ae0abde6e655d7186cebc6afGlenn Kasten
31332a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten// Map an interface to it's corresponding IObject.
31432a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten// Note: this operation is undefined on IObject, as it lacks an mThis.
31532a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten// If you have an IObject, then you're done -- you already have what you need.
31632a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten
31750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten#define InterfaceToIObject(thiz) ((thiz)->mThis)
31832a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten
31950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten#define InterfaceToCAudioPlayer(thiz) (((CAudioPlayer*)InterfaceToIObject(thiz)))
320da18bcf20d4cceb715904717a5a8b1585f935080Jean-Michel Trivi
32150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten#define InterfaceToCAudioRecorder(thiz) (((CAudioRecorder*)InterfaceToIObject(thiz)))
322bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Trivi
323b27faa17b2fab644350c0264b23e18a5b388a8adGlenn Kasten#define InterfaceToCAudioRecorder(thiz) (((CAudioRecorder*)InterfaceToIObject(thiz)))
324b27faa17b2fab644350c0264b23e18a5b388a8adGlenn Kasten
32578fcbe58abb7f85a837048d459e7dd5510a594e1Jean-Michel Trivi#define InterfaceToCMediaPlayer(thiz) (((CMediaPlayer*)InterfaceToIObject(thiz)))
32678fcbe58abb7f85a837048d459e7dd5510a594e1Jean-Michel Trivi
3279db8335361c67c4ed877f68218835df96ce43a4bJean-Michel Trivi#ifdef ANDROID
328551f769ee0234ca22c97dbbf84d87f2c1e19fa80Jean-Michel Trivi#include "android/MediaPlayer_to_android.h"
329551f769ee0234ca22c97dbbf84d87f2c1e19fa80Jean-Michel Trivi#include "android/OutputMix_to_android.h"
330551f769ee0234ca22c97dbbf84d87f2c1e19fa80Jean-Michel Trivi#include "android/AudioPlayer_to_android.h"
331551f769ee0234ca22c97dbbf84d87f2c1e19fa80Jean-Michel Trivi#include "android/AudioRecorder_to_android.h"
332f6f90fc5202248e2ae0abde6e655d7186cebc6afGlenn Kasten#endif
333f6f90fc5202248e2ae0abde6e655d7186cebc6afGlenn Kasten
334b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastenextern predestroy_t C3DGroup_PreDestroy(void *self);
33531df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten
33609f49a84b259d8b8c49a4d71b42ea801b2a9e8f2Glenn Kastenextern SLresult CAudioPlayer_Realize(void *self, SLboolean async);
3374f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kastenextern SLresult CAudioPlayer_Resume(void *self, SLboolean async);
33809f49a84b259d8b8c49a4d71b42ea801b2a9e8f2Glenn Kastenextern void CAudioPlayer_Destroy(void *self);
339b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastenextern predestroy_t CAudioPlayer_PreDestroy(void *self);
340bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Trivi
341bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Triviextern SLresult CAudioRecorder_Realize(void *self, SLboolean async);
342bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Triviextern SLresult CAudioRecorder_Resume(void *self, SLboolean async);
343bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Triviextern void CAudioRecorder_Destroy(void *self);
344b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastenextern predestroy_t CAudioRecorder_PreDestroy(void *self);
345bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Trivi
346437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenextern SLresult CEngine_Realize(void *self, SLboolean async);
3474f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kastenextern SLresult CEngine_Resume(void *self, SLboolean async);
348437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenextern void CEngine_Destroy(void *self);
349b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastenextern predestroy_t CEngine_PreDestroy(void *self);
350d78ef68025c4de08bffaa318d0057d8affac81a1Glenn Kastenextern void CEngine_Destroyed(CEngine *self);
351bdb243c16be832f5853083480965a437b81df3c8Jean-Michel Trivi
352dc098b54cd7df1b79b4560ae0570d88e4b9f751eJean-Michel Triviextern SLresult COutputMix_Realize(void *self, SLboolean async);
353dc098b54cd7df1b79b4560ae0570d88e4b9f751eJean-Michel Triviextern SLresult COutputMix_Resume(void *self, SLboolean async);
354dc098b54cd7df1b79b4560ae0570d88e4b9f751eJean-Michel Triviextern void COutputMix_Destroy(void *self);
355b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastenextern predestroy_t COutputMix_PreDestroy(void *self);
356dc098b54cd7df1b79b4560ae0570d88e4b9f751eJean-Michel Trivi
357da97f083b47fa4442a40ad962ed86a922a537a64Glenn Kastenextern SLresult CMediaPlayer_Realize(void *self, SLboolean async);
358da97f083b47fa4442a40ad962ed86a922a537a64Glenn Kastenextern SLresult CMediaPlayer_Resume(void *self, SLboolean async);
359da97f083b47fa4442a40ad962ed86a922a537a64Glenn Kastenextern void CMediaPlayer_Destroy(void *self);
360b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastenextern predestroy_t CMediaPlayer_PreDestroy(void *self);
361da97f083b47fa4442a40ad962ed86a922a537a64Glenn Kasten
36299cd40bd94b21ff01fa9391b04d8dd1fa7a05da7Glenn Kasten#ifdef USE_SDL
363bc1596c33e134859d3ae3182d641b2dd03405b5dGlenn Kastenextern void SDL_open(IEngine *thisEngine);
364bc1596c33e134859d3ae3182d641b2dd03405b5dGlenn Kastenextern void SDL_close(void);
36599cd40bd94b21ff01fa9391b04d8dd1fa7a05da7Glenn Kasten#endif
36603201d85351a107e59cf61b321a530351790e06cGlenn Kasten
367bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten#define SL_OBJECT_STATE_REALIZING_1  ((SLuint32) 0x4) // async realize on work queue
368bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten#define SL_OBJECT_STATE_REALIZING_2  ((SLuint32) 0x5) // sync realize, or async realize hook
369bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten#define SL_OBJECT_STATE_RESUMING_1   ((SLuint32) 0x6) // async resume on work queue
370bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten#define SL_OBJECT_STATE_RESUMING_2   ((SLuint32) 0x7) // sync resume, or async resume hook
371bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten#define SL_OBJECT_STATE_SUSPENDING   ((SLuint32) 0x8) // suspend in progress
372bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten#define SL_OBJECT_STATE_REALIZING_1A ((SLuint32) 0x9) // abort while async realize on work queue
373bcf6e4f2a46544f599f6c77354650c6aad91ea5dGlenn Kasten#define SL_OBJECT_STATE_RESUMING_1A  ((SLuint32) 0xA) // abort while async resume on work queue
3744f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kasten#define SL_OBJECT_STATE_DESTROYING   ((SLuint32) 0xB) // destroy object when no strong references
37503201d85351a107e59cf61b321a530351790e06cGlenn Kasten
37603201d85351a107e59cf61b321a530351790e06cGlenn Kasten#ifdef USE_OUTPUTMIXEXT
37703201d85351a107e59cf61b321a530351790e06cGlenn Kasten#define SL_PLAYSTATE_STOPPING ((SLuint32) 0x4) // Play::Stop while PLAYING
37803201d85351a107e59cf61b321a530351790e06cGlenn Kasten// If we needed it, could have PLAYING mean mixer is currently reading from front buffer,
37903201d85351a107e59cf61b321a530351790e06cGlenn Kasten// while PLAYABLE would mean application requested PLAYING, but buffer queue is empty
38003201d85351a107e59cf61b321a530351790e06cGlenn Kasten#endif
38103201d85351a107e59cf61b321a530351790e06cGlenn Kasten
382227b8b5fe36d5385bbb23d63198bc8e72bfda5d3Glenn Kasten#ifndef ANDROID
383437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenextern void *sync_start(void *arg);
384227b8b5fe36d5385bbb23d63198bc8e72bfda5d3Glenn Kasten#endif
385437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenextern SLresult err_to_result(int err);
386277aee45eabf5d756a7e0de49efee2ee1c0d9640Glenn Kasten
387277aee45eabf5d756a7e0de49efee2ee1c0d9640Glenn Kasten#ifdef __GNUC__
38832a32a4674ed760e1ab6bf4b4349216bbfa75735Glenn Kasten#define ctz __builtin_ctz
389277aee45eabf5d756a7e0de49efee2ee1c0d9640Glenn Kasten#else
390277aee45eabf5d756a7e0de49efee2ee1c0d9640Glenn Kastenextern unsigned ctz(unsigned);
391277aee45eabf5d756a7e0de49efee2ee1c0d9640Glenn Kasten#endif
3927e5dd9fa6ab032d7eeaac79bee4370a133eda8c2Glenn Kastenextern const char * const interface_names[MPH_MAX];
39315f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten#include "platform.h"
394b27faa17b2fab644350c0264b23e18a5b388a8adGlenn Kasten#include "attr.h"
395b27faa17b2fab644350c0264b23e18a5b388a8adGlenn Kasten#include "handlers.h"
39634a2d76d36b5b50a5792963b14ab2ce3bfed1086Glenn Kasten#include "trace.h"
39723c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten
39823c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#ifdef USE_SNDFILE
39923c38816f7c210afae5072fd44658c98fec7e119Glenn Kastenextern void audioPlayerTransportUpdate(CAudioPlayer *audioPlayer);
40023c38816f7c210afae5072fd44658c98fec7e119Glenn Kasten#endif
4019c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten
4029c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kastenextern SLresult IBufferQueue_Enqueue(SLBufferQueueItf self, const void *pBuffer, SLuint32 size);
4039c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kastenextern SLresult IBufferQueue_Clear(SLBufferQueueItf self);
4049c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kastenextern SLresult IBufferQueue_RegisterCallback(SLBufferQueueItf self,
4059c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten    slBufferQueueCallback callback, void *pContext);
4069c03f04a9c6cc2a821182c8be8f2efe964a27efeGlenn Kasten
40750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kastenextern bool IsInterfaceInitialized(IObject *thiz, unsigned MPH);
4084f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kastenextern SLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID);
4094f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kastenextern void ReleaseStrongRef(IObject *object);
4104f924ff768d761f53db6fa2dbfb794ba7a65e776Glenn Kastenextern void ReleaseStrongRefAndUnlockExclusive(IObject *object);
41131df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kasten
41231df22b193ea7c7c331d26a27fa6756a89c8ec3cGlenn Kastenextern COutputMix *CAudioPlayer_GetOutputMix(CAudioPlayer *audioPlayer);
4133be625f40588941aa23e35fed5cb693ddc9718daGlenn Kastenextern SLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
4143be625f40588941aa23e35fed5cb693ddc9718daGlenn Kasten    SLuint32 *pIndex, SLuint32 *pLEDDeviceID, SLLEDDescriptor *pDescriptor);
4153be625f40588941aa23e35fed5cb693ddc9718daGlenn Kastenextern SLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
4163be625f40588941aa23e35fed5cb693ddc9718daGlenn Kasten    SLuint32 *pIndex, SLuint32 *pVibraDeviceID, SLVibraDescriptor *pDescriptor);
417a930d729ff2249eaa0b45a5e61c70bebad45f698Glenn Kasten
418a930d729ff2249eaa0b45a5e61c70bebad45f698Glenn Kastenextern CEngine *theOneTrueEngine;
419a930d729ff2249eaa0b45a5e61c70bebad45f698Glenn Kastenextern pthread_mutex_t theOneTrueMutex;
420b11def0293629d4d44ddbcd8a27c63504fd80ce1Glenn Kastenextern unsigned theOneTrueRefCount;
4217a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kasten
4227a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kastenextern LI_API SLresult liCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
4237a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kasten    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
4247a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kasten    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired,
4257a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kasten    const ClassTable *pCEngine_class);
4267a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kastenextern LI_API SLresult liQueryNumSupportedInterfaces(SLuint32 *pNumSupportedInterfaces,
4277a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kasten        const ClassTable *clazz);
4287a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kastenextern LI_API SLresult liQuerySupportedInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId,
4297a236ec592297f93094698e599cc2ffe5a1542e5Glenn Kasten        const ClassTable *clazz);
430e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten
431e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// The EnqueueAsyncCallback macros provide a safe way to asynchronously call an application-level
432e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// callback handler that is permitted to do almost anything, including block.  This is intended
433e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// primarily for "notification" callbacks such as play head progress.  Do not use for callbacks
434e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// which must be synchronous, such as buffer queue completions.  The enqueue may fail if
435e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// the callback queue is full.  This almost always indicates an application error such as blocking
436e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// for an excessive time within a callback handler or requesting too frequent callbacks.  The
437e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// recommended recovery is to either retry later, or log a warning or error as appropriate.
438e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// If the callback absolutely must be called, then you should be calling it directly instead.
439e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// Example usage:
440e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//  CAudioPlayer *ap;
441e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//  SLresult result = EnqueueAsyncCallback_ppi(ap, playCallback, &ap->mPlay.mItf, playContext,
442e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//       SL_PLAYEVENT_HEADATEND);
443e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//  if (SL_RESULT_SUCCESS != result) {
444e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//    LOGW("Callback %p(%p, %p, SL_PLAYEVENT_HEADATEND) dropped", playCallback, &ap->mPlay.mItf,
445e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//        playContext);
446e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//  }
447e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten// which replaces:
448e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten//  (*playCallback)(&ap->mPlay.mItf, playContext, SL_PLAYEVENT_HEADATEND);
449e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten#define EnqueueAsyncCallback_ppi(object, handler, p1, p2, i1) \
450e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten        ThreadPool_add_ppi(&(object)->mObject.mEngine->mThreadPool, \
451e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten            (ClosureHandler_ppi) (handler), (p1), (p2), (i1))
452e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten#define EnqueueAsyncCallback_ppii(object, handler, p1, p2, i1, i2) \
453e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten        ThreadPool_add_ppii(&(object)->mObject.mEngine->mThreadPool, \
454e3f866849da11bb2da4c9f4fa88afcb9addd47beGlenn Kasten            (ClosureHandler_ppii) (handler), (p1), (p2), (i1), (i2))
455b1af3dc1062b74d5b47d9c81a037d99ed1dc5ef8Jean-Michel Trivi#define EnqueueAsyncCallback_piipp(object, handler, p1, i1, i2, p2, p3) \
456b1af3dc1062b74d5b47d9c81a037d99ed1dc5ef8Jean-Michel Trivi        ThreadPool_add_piipp(&(object)->mObject.mEngine->mThreadPool, \
457b1af3dc1062b74d5b47d9c81a037d99ed1dc5ef8Jean-Michel Trivi            (ClosureHandler_piipp) (handler), (p1), (i1), (i2), (p2), (p3))
458c63c2a7b0e63545b4b7073850e8583fd6010b0eeGlenn Kasten
459c63c2a7b0e63545b4b7073850e8583fd6010b0eeGlenn Kasten#define SL_PREFETCHEVENT_NONE ((SLuint32) 0)    // placeholder for non-existent SL_PREFETCHEVENT_*
460