src/audio/openslES/SDL_openslES.c
changeset 12534 682d9b5ecbed
child 12538 fad97a498ffb
equal deleted inserted replaced
12533:eb22f5f6d5a5 12534:682d9b5ecbed
       
     1 /*
       
     2   Simple DirectMedia Layer
       
     3   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
       
     4 
       
     5   This software is provided 'as-is', without any express or implied
       
     6   warranty.  In no event will the authors be held liable for any damages
       
     7   arising from the use of this software.
       
     8 
       
     9   Permission is granted to anyone to use this software for any purpose,
       
    10   including commercial applications, and to alter it and redistribute it
       
    11   freely, subject to the following restrictions:
       
    12 
       
    13   1. The origin of this software must not be misrepresented; you must not
       
    14      claim that you wrote the original software. If you use this software
       
    15      in a product, an acknowledgment in the product documentation would be
       
    16      appreciated but is not required.
       
    17   2. Altered source versions must be plainly marked as such, and must not be
       
    18      misrepresented as being the original software.
       
    19   3. This notice may not be removed or altered from any source distribution.
       
    20 */
       
    21 #include "../../SDL_internal.h"
       
    22 
       
    23 #if SDL_AUDIO_DRIVER_OPENSLES
       
    24 
       
    25 #include "SDL_audio.h"
       
    26 #include "../SDL_audio_c.h"
       
    27 #include "SDL_openslES.h"
       
    28 
       
    29 // for native audio
       
    30 #include <SLES/OpenSLES.h>
       
    31 #include <SLES/OpenSLES_Android.h>
       
    32 
       
    33 #include <android/log.h>
       
    34 
       
    35 #define LOG_TAG "SDL_openslES"
       
    36 
       
    37 //#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
       
    38 //#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
       
    39 //#define LOGI(...) do {} while (0)
       
    40 //#define LOGE(...) do {} while (0)
       
    41 #define LOGI(...)
       
    42 #define LOGE(...)
       
    43 
       
    44 // engine interfaces
       
    45 static SLObjectItf engineObject = NULL;
       
    46 static SLEngineItf engineEngine;
       
    47 
       
    48 // output mix interfaces
       
    49 static SLObjectItf outputMixObject = NULL;
       
    50 //static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;
       
    51 
       
    52 // aux effect on the output mix, used by the buffer queue player
       
    53 static const SLEnvironmentalReverbSettings reverbSettings =
       
    54     SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;
       
    55 
       
    56 // buffer queue player interfaces
       
    57 static SLObjectItf						bqPlayerObject = NULL;
       
    58 static SLPlayItf 						bqPlayerPlay;
       
    59 static SLAndroidSimpleBufferQueueItf	bqPlayerBufferQueue;
       
    60 //static SLEffectSendItf					bqPlayerEffectSend;
       
    61 static SLMuteSoloItf					bqPlayerMuteSolo;
       
    62 static SLVolumeItf						bqPlayerVolume;
       
    63 
       
    64 // recorder interfaces TODO
       
    65 static SLObjectItf						recorderObject = NULL;
       
    66 static SLRecordItf						recorderRecord;
       
    67 static SLAndroidSimpleBufferQueueItf	recorderBufferQueue;
       
    68 
       
    69 // pointer and size of the next player buffer to enqueue, and number of remaining buffers
       
    70 static short 	*nextBuffer;
       
    71 static unsigned	nextSize;
       
    72 static int 		nextCount;
       
    73 
       
    74 static const char	*sldevaudiorecorderstr	= "SLES Audio Recorder";
       
    75 static const char	*sldevaudioplayerstr 	= "SLES Audio Player";
       
    76 
       
    77 #define	SLES_DEV_AUDIO_RECORDER	sldevaudiorecorderstr
       
    78 #define	SLES_DEV_AUDIO_PLAYER	sldevaudioplayerstr
       
    79 
       
    80 #define NUM_BUFFERS 2           /* -- Don't lower this! */
       
    81 
       
    82 static	Uint8	*mixbuff = NULL;
       
    83 static	int		next_buffer = 0;
       
    84 static	Uint8	*pmixbuff[NUM_BUFFERS];
       
    85 
       
    86 static SDL_sem *playsem = NULL, *recsem = NULL;
       
    87 
       
    88 //static SDL_AudioDevice* audioDevice = NULL;
       
    89 
       
    90 #if 0
       
    91 static void openslES_DetectDevices( int iscapture )
       
    92 {
       
    93 	LOGI( "openSLES_DetectDevices()" );
       
    94     if ( iscapture )
       
    95             addfn( SLES_DEV_AUDIO_RECORDER );
       
    96 	else
       
    97             addfn( SLES_DEV_AUDIO_PLAYER );
       
    98 	return;
       
    99 }
       
   100 #endif
       
   101 
       
   102 static void openslES_DestroyEngine( void );
       
   103 
       
   104 static int	openslES_CreateEngine( void )
       
   105 {
       
   106 	SLresult result;
       
   107 
       
   108 	LOGI( "openSLES_CreateEngine()" );
       
   109 
       
   110 	// create engine
       
   111 	result = slCreateEngine( &engineObject, 0, NULL, 0, NULL, NULL );
       
   112 	if ( SL_RESULT_SUCCESS != result ) {
       
   113 
       
   114 		LOGE( "slCreateEngine failed" );
       
   115 		goto error;
       
   116 	}
       
   117 
       
   118 	LOGI( "slCreateEngine OK" );
       
   119 
       
   120     // realize the engine
       
   121     result = (*engineObject)->Realize( engineObject, SL_BOOLEAN_FALSE );
       
   122 	if ( SL_RESULT_SUCCESS != result ) {
       
   123 
       
   124 		LOGE( "RealizeEngine failed" );
       
   125 		goto error;
       
   126 	}
       
   127 
       
   128 	LOGI( "RealizeEngine OK" );
       
   129 
       
   130     // get the engine interface, which is needed in order to create other objects
       
   131     result = (*engineObject)->GetInterface( engineObject, SL_IID_ENGINE, &engineEngine );
       
   132 	if ( SL_RESULT_SUCCESS != result ) {
       
   133 
       
   134 		LOGE( "EngineGetInterface failed" );
       
   135 		goto error;
       
   136 	}
       
   137 
       
   138 	LOGI( "EngineGetInterface OK" );
       
   139 
       
   140     // create output mix, with environmental reverb specified as a non-required interface
       
   141 //  const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB };
       
   142 //  const SLboolean req[1] = { SL_BOOLEAN_FALSE };
       
   143 
       
   144   const SLInterfaceID ids[1] = { SL_IID_VOLUME };
       
   145   const SLboolean req[1] = { SL_BOOLEAN_FALSE };
       
   146   result = (*engineEngine)->CreateOutputMix( engineEngine, &outputMixObject, 1, ids, req );
       
   147 
       
   148 	if ( SL_RESULT_SUCCESS != result ) {
       
   149 
       
   150 		LOGE( "CreateOutputMix failed" );
       
   151 		goto error;
       
   152 	}
       
   153 	LOGI( "CreateOutputMix OK" );
       
   154 
       
   155   // realize the output mix
       
   156   result = (*outputMixObject)->Realize( outputMixObject, SL_BOOLEAN_FALSE );
       
   157 	if ( SL_RESULT_SUCCESS != result ) {
       
   158 
       
   159 		LOGE( "RealizeOutputMix failed" );
       
   160 		goto error;
       
   161 	}
       
   162 
       
   163 	return 1;
       
   164 
       
   165 error:;
       
   166 	openslES_DestroyEngine( );
       
   167 	return 0;
       
   168 }
       
   169 
       
   170 static	void	openslES_DestroyPCMPlayer( void );
       
   171 static	void	openslES_DestroyPCMRecorder( void );
       
   172 
       
   173 static void openslES_DestroyEngine( void )
       
   174 {
       
   175 	LOGI( "openslES_DestroyEngine()" );
       
   176 
       
   177 	openslES_DestroyPCMPlayer( );
       
   178 	openslES_DestroyPCMRecorder( );
       
   179 
       
   180 	// destroy output mix object, and invalidate all associated interfaces
       
   181 	if ( outputMixObject != NULL ) {
       
   182 
       
   183 	    (*outputMixObject)->Destroy( outputMixObject );
       
   184 	    outputMixObject = NULL;
       
   185 //	    outputMixEnvironmentalReverb = NULL;
       
   186 	}
       
   187 
       
   188 	// destroy engine object, and invalidate all associated interfaces
       
   189 	if (engineObject != NULL) {
       
   190 
       
   191 	    (*engineObject)->Destroy( engineObject );
       
   192 	    engineObject = NULL;
       
   193 	    engineEngine = NULL;
       
   194 	}
       
   195 
       
   196 	return;
       
   197 }
       
   198 
       
   199 // this callback handler is called every time a buffer finishes playing
       
   200 static void bqPlayerCallback( SLAndroidSimpleBufferQueueItf bq, void *context )
       
   201 {
       
   202 	static int	t = 0;
       
   203 //    assert(bq == bqPlayerBufferQueue);
       
   204 //    assert(NULL == context);
       
   205 
       
   206     // for streaming playback, replace this test by logic to find and fill the next buffer
       
   207 #if 0
       
   208 	if (--nextCount > 0 && NULL != nextBuffer && 0 != nextSize) {
       
   209 		SLresult result;
       
   210 		// enqueue another buffer
       
   211 		result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
       
   212 		// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
       
   213 		// which for this code example would indicate a programming error
       
   214 		assert(SL_RESULT_SUCCESS == result);
       
   215 		(void)result;
       
   216 	}
       
   217 #endif
       
   218 
       
   219 	LOGI( "SLES: Playback Callmeback %u", t++ );
       
   220 
       
   221 	SDL_SemPost( playsem );
       
   222 
       
   223 	return;
       
   224 }
       
   225 
       
   226 static int openslES_CreatePCMRecorder( _THIS )
       
   227 {
       
   228 	LOGE( "openslES_CreatePCMRecorder not implimented yet!" );
       
   229 	return SDL_SetError( "openslES_CreatePCMRecorder not implimented yet!" );
       
   230 }
       
   231 
       
   232 static void openslES_DestroyPCMRecorder( void )
       
   233 {
       
   234 	return;
       
   235 }
       
   236 
       
   237 static int openslES_CreatePCMPlayer( _THIS )
       
   238 {
       
   239 	SLDataFormat_PCM format_pcm;
       
   240   SDL_AudioFormat	test_format;
       
   241 	SLresult result;
       
   242 	int	i;
       
   243 
       
   244 /*
       
   245 	test_format = SDL_FirstAudioFormat( this->spec.format );
       
   246 
       
   247 	while ( test_format != 0 ) {
       
   248 
       
   249 		if ( SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format ) ) break;
       
   250 		test_format = SDL_NextAudioFormat( );
       
   251 	}
       
   252 
       
   253 	if ( test_format == 0 ) {
       
   254 
       
   255 		// Didn't find a compatible format :( 
       
   256 		LOGI( "No compatible audio format!" );
       
   257 		return SDL_SetError("No compatible audio format!");
       
   258 	}
       
   259 
       
   260 	this->spec.format = test_format;
       
   261 */
       
   262 
       
   263  // Update the fragment size as size in bytes 
       
   264  SDL_CalculateAudioSpec( &this->spec );
       
   265 
       
   266 	LOGI( "Try to open %u hz %u bit chan %u %s samples %u", 
       
   267 			this->spec.freq, SDL_AUDIO_BITSIZE( this->spec.format ), 
       
   268 			this->spec.channels, (test_format&0x1000) ? "BE" : "LE", this->spec.samples 
       
   269 		);
       
   270 
       
   271 	// configure audio source
       
   272 	SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2 };
       
   273 //	SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, OPENSLES_BUFFERS };
       
   274 
       
   275 	format_pcm.formatType    = SL_DATAFORMAT_PCM;
       
   276 	format_pcm.numChannels   = this->spec.channels;
       
   277 	format_pcm.samplesPerSec = this->spec.freq * 1000;	/// kilo Hz to milli Hz
       
   278 	format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE( this->spec.format );
       
   279 	format_pcm.containerSize = SDL_AUDIO_BITSIZE( this->spec.format );
       
   280 
       
   281 	if ( SDL_AUDIO_ISBIGENDIAN( this->spec.format ) )
       
   282 		format_pcm.endianness = SL_BYTEORDER_BIGENDIAN;
       
   283 	else
       
   284 		format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
       
   285 
       
   286 /*
       
   287 #define SL_SPEAKER_FRONT_LEFT			((SLuint32) 0x00000001)
       
   288 #define SL_SPEAKER_FRONT_RIGHT			((SLuint32) 0x00000002)
       
   289 #define SL_SPEAKER_FRONT_CENTER			((SLuint32) 0x00000004)
       
   290 #define SL_SPEAKER_LOW_FREQUENCY			((SLuint32) 0x00000008)
       
   291 #define SL_SPEAKER_BACK_LEFT			((SLuint32) 0x00000010)
       
   292 #define SL_SPEAKER_BACK_RIGHT			((SLuint32) 0x00000020)
       
   293 #define SL_SPEAKER_FRONT_LEFT_OF_CENTER	((SLuint32) 0x00000040)
       
   294 #define SL_SPEAKER_FRONT_RIGHT_OF_CENTER	((SLuint32) 0x00000080)
       
   295 #define SL_SPEAKER_BACK_CENTER			((SLuint32) 0x00000100)
       
   296 #define SL_SPEAKER_SIDE_LEFT			((SLuint32) 0x00000200)
       
   297 #define SL_SPEAKER_SIDE_RIGHT			((SLuint32) 0x00000400)
       
   298 #define SL_SPEAKER_TOP_CENTER			((SLuint32) 0x00000800)
       
   299 #define SL_SPEAKER_TOP_FRONT_LEFT		((SLuint32) 0x00001000)
       
   300 #define SL_SPEAKER_TOP_FRONT_CENTER		((SLuint32) 0x00002000)
       
   301 #define SL_SPEAKER_TOP_FRONT_RIGHT		((SLuint32) 0x00004000)
       
   302 #define SL_SPEAKER_TOP_BACK_LEFT			((SLuint32) 0x00008000)
       
   303 #define SL_SPEAKER_TOP_BACK_CENTER		((SLuint32) 0x00010000)
       
   304 #define SL_SPEAKER_TOP_BACK_RIGHT		((SLuint32) 0x00020000)
       
   305 */
       
   306 
       
   307 	if ( this->spec.channels == 1 )
       
   308 		format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER;
       
   309 	else if ( this->spec.channels == 2 )
       
   310 		format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
       
   311 	else if ( this->spec.channels == 3 )
       
   312 		format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER;
       
   313 	else if ( this->spec.channels == 4 )
       
   314 		format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
       
   315 								 SL_SPEAKER_BACK_LEFT  | SL_SPEAKER_BACK_RIGHT;
       
   316 	else
       
   317 		format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT |
       
   318 								 SL_SPEAKER_BACK_LEFT  | SL_SPEAKER_BACK_RIGHT |
       
   319 								 SL_SPEAKER_FRONT_CENTER;
       
   320 
       
   321 	SLDataSource audioSrc = { &loc_bufq, &format_pcm };
       
   322 
       
   323 	// configure audio sink
       
   324 	SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject };
       
   325 	SLDataSink audioSnk = { &loc_outmix, NULL };
       
   326 
       
   327     // create audio player
       
   328     const SLInterfaceID ids[2] = { 
       
   329 			SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
       
   330 			SL_IID_VOLUME 
       
   331 			};
       
   332 
       
   333     const SLboolean req[2] = { 
       
   334 			SL_BOOLEAN_TRUE, 
       
   335 			SL_BOOLEAN_FALSE,
       
   336 			};
       
   337 
       
   338 	result = (*engineEngine)->CreateAudioPlayer( engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
       
   339 				2, ids, req );
       
   340 	if ( SL_RESULT_SUCCESS != result ) {
       
   341 
       
   342 		LOGE( "CreateAudioPlayer failed" );
       
   343 		goto failed;
       
   344 	}
       
   345 
       
   346     // realize the player
       
   347 	result = (*bqPlayerObject)->Realize( bqPlayerObject, SL_BOOLEAN_FALSE );
       
   348 	if ( SL_RESULT_SUCCESS != result ) {
       
   349 
       
   350 		LOGE( "RealizeAudioPlayer failed" );
       
   351 		goto failed;
       
   352 	}
       
   353 
       
   354 	// get the play interface
       
   355 	result = (*bqPlayerObject)->GetInterface( bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay );
       
   356 	if ( SL_RESULT_SUCCESS != result ) {
       
   357 
       
   358 		LOGE( "SL_IID_PLAY interface get failed" );
       
   359 		goto failed;
       
   360 	}
       
   361 
       
   362     // get the buffer queue interface
       
   363 	result = (*bqPlayerObject)->GetInterface( bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bqPlayerBufferQueue );
       
   364 	if ( SL_RESULT_SUCCESS != result ) {
       
   365 
       
   366 		LOGE( "SL_IID_BUFFERQUEUE interface get failed" );
       
   367 		goto failed;
       
   368 	}
       
   369 
       
   370 	// register callback on the buffer queue
       
   371 	result = (*bqPlayerBufferQueue)->RegisterCallback( bqPlayerBufferQueue, bqPlayerCallback, NULL );
       
   372 	if ( SL_RESULT_SUCCESS != result ) {
       
   373 
       
   374 		LOGE( "RegisterCallback failed" );
       
   375 		goto failed;
       
   376 	}
       
   377 
       
   378 #if 0
       
   379     // get the effect send interface
       
   380 	result = (*bqPlayerObject)->GetInterface( bqPlayerObject, SL_IID_EFFECTSEND, &bqPlayerEffectSend );
       
   381 	if ( SL_RESULT_SUCCESS != result ) {
       
   382 
       
   383 		LOGE( "SL_IID_EFFECTSEND interface get failed" );
       
   384 		goto failed;
       
   385 	}
       
   386 #endif
       
   387 
       
   388 #if 0   // mute/solo is not supported for sources that are known to be mono, as this is
       
   389     // get the mute/solo interface
       
   390     result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_MUTESOLO, &bqPlayerMuteSolo);
       
   391     assert(SL_RESULT_SUCCESS == result);
       
   392     (void)result;
       
   393 #endif
       
   394 
       
   395     // get the volume interface
       
   396 	result = (*bqPlayerObject)->GetInterface( bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume );
       
   397 	if ( SL_RESULT_SUCCESS != result ) {
       
   398 
       
   399 		LOGE( "SL_IID_VOLUME interface get failed" );
       
   400 //		goto failed;
       
   401 	}
       
   402 
       
   403 	// set the player's state to playing
       
   404 	result = (*bqPlayerPlay)->SetPlayState( bqPlayerPlay, SL_PLAYSTATE_PLAYING );
       
   405 	if ( SL_RESULT_SUCCESS != result ) {
       
   406 
       
   407 		LOGE( "Play set state failed" );
       
   408 		goto failed;
       
   409 	}
       
   410 
       
   411     /* Create the audio buffer semaphore */
       
   412 	playsem = SDL_CreateSemaphore( NUM_BUFFERS - 1 );
       
   413 	if ( !playsem ) {
       
   414 
       
   415 		LOGE( "cannot create Semaphore!" );
       
   416 		goto failed;
       
   417 	}
       
   418 
       
   419 	/* Create the sound buffers */
       
   420 	mixbuff = (Uint8 *) SDL_malloc( NUM_BUFFERS * this->spec.size );
       
   421 	if ( mixbuff == NULL) {
       
   422 
       
   423 		LOGE( "mixbuffer allocate - out of memory" );
       
   424 		goto failed;
       
   425 	}
       
   426 
       
   427 	for ( i = 0; i < NUM_BUFFERS; i ++ )
       
   428 		pmixbuff[i] = mixbuff + i * this->spec.size;
       
   429 
       
   430     return 0;
       
   431 
       
   432 failed:;
       
   433 
       
   434 	openslES_DestroyPCMPlayer( );
       
   435 
       
   436 	return SDL_SetError( "Open device failed!" );
       
   437 }
       
   438 
       
   439 static void openslES_DestroyPCMPlayer( void )
       
   440 {
       
   441 	// destroy buffer queue audio player object, and invalidate all associated interfaces
       
   442 	if ( bqPlayerObject != NULL ) {
       
   443 
       
   444         (*bqPlayerObject)->Destroy( bqPlayerObject );
       
   445 
       
   446         bqPlayerObject		= NULL;
       
   447         bqPlayerPlay		= NULL;
       
   448         bqPlayerBufferQueue = NULL;
       
   449 //        bqPlayerEffectSend	= NULL;
       
   450         bqPlayerMuteSolo	= NULL;
       
   451         bqPlayerVolume		= NULL;
       
   452     }
       
   453 
       
   454 	if ( playsem ) {
       
   455 
       
   456 		SDL_DestroySemaphore( playsem );
       
   457 		playsem = NULL;
       
   458 	}
       
   459 
       
   460 	if ( mixbuff )
       
   461 		SDL_free( mixbuff );
       
   462 
       
   463 	return;
       
   464 }
       
   465 
       
   466 static int openslES_OpenDevice( _THIS, void *handle, const char *devname, int iscapture )
       
   467 {
       
   468 	if ( iscapture ) {
       
   469 		LOGI( "openslES_OpenDevice( ) %s for capture", devname );
       
   470 		return openslES_CreatePCMRecorder( this );
       
   471 	}
       
   472 
       
   473 	LOGI( "openslES_OpenDevice( ) %s for playing", devname );
       
   474 
       
   475 	return openslES_CreatePCMPlayer( this );
       
   476 }
       
   477 
       
   478 static void openslES_CloseDevice( _THIS )
       
   479 {
       
   480 	if ( this->iscapture ) {
       
   481 		LOGI( "openslES_CloseDevice( ) for capture" );
       
   482 		return openslES_DestroyPCMRecorder( );
       
   483 	}
       
   484 
       
   485 	LOGI( "openslES_CloseDevice( ) for playing" );
       
   486 	openslES_DestroyPCMPlayer( );
       
   487 
       
   488 	return;
       
   489 }
       
   490 
       
   491 static void openslES_WaitDevice( _THIS )
       
   492 {
       
   493 	LOGI( "openslES_WaitDevice( )" );
       
   494 
       
   495     /* Wait for an audio chunk to finish */
       
   496 //    WaitForSingleObject(this->hidden->audio_sem, INFINITE);
       
   497 	SDL_SemWait( playsem );
       
   498 
       
   499 	return;
       
   500 }
       
   501 
       
   502 ///           n   playn sem
       
   503 // getbuf     0   -     1
       
   504 // fill buff  0   -     1
       
   505 // play       0 - 0     1
       
   506 // wait       1   0     0
       
   507 // getbuf     1   0     0
       
   508 // fill buff  1   0     0
       
   509 // play       0   0     0
       
   510 // wait       
       
   511 //
       
   512 // okay..
       
   513 
       
   514 
       
   515 static Uint8 *openslES_GetDeviceBuf( _THIS )
       
   516 {
       
   517 	LOGI( "openslES_GetDeviceBuf( )" );
       
   518 
       
   519     return pmixbuff[next_buffer];
       
   520 }
       
   521 
       
   522 static void openslES_PlayDevice( _THIS )
       
   523 {
       
   524 	SLresult result;
       
   525 
       
   526 	LOGI( "======openslES_PlayDevice( )======" );
       
   527     /* Queue it up */
       
   528 
       
   529 	result = (*bqPlayerBufferQueue)->Enqueue( bqPlayerBufferQueue, pmixbuff[next_buffer], this->spec.size );
       
   530 	if ( SL_RESULT_SUCCESS != result ) { 
       
   531 		// just puk here
       
   532 		// next !
       
   533 	}
       
   534 
       
   535 	next_buffer ++;
       
   536 	if ( next_buffer >= NUM_BUFFERS ) next_buffer = 0;
       
   537 
       
   538 	return;
       
   539 }
       
   540 
       
   541 static int openslES_Init( SDL_AudioDriverImpl * impl )
       
   542 {
       
   543 	LOGI( "openslES_Init() called" );
       
   544 
       
   545 	if ( !openslES_CreateEngine() ) return 0;
       
   546 
       
   547 	LOGI( "openslES_Init() - set pointers" );
       
   548 
       
   549 	/* Set the function pointers */
       
   550 //	impl->DetectDevices = openslES_DetectDevices;
       
   551 	impl->OpenDevice    = openslES_OpenDevice;
       
   552    impl->PlayDevice	= openslES_PlayDevice;
       
   553    impl->GetDeviceBuf	= openslES_GetDeviceBuf;
       
   554 	impl->Deinitialize  = openslES_DestroyEngine;
       
   555    impl->WaitDevice	= openslES_WaitDevice;
       
   556 
       
   557 	/* and the capabilities */
       
   558 	impl->HasCaptureSupport = 0; /* TODO */
       
   559 	impl->OnlyHasDefaultOutputDevice = 1;
       
   560 //	impl->OnlyHasDefaultInputDevice  = 1;
       
   561 
       
   562 	LOGI( "openslES_Init() - succes" );
       
   563 
       
   564 	return 1;   /* this audio target is available. */
       
   565 }
       
   566 
       
   567 AudioBootStrap openslES_bootstrap = {
       
   568 	"openslES", "opensl ES audio driver", openslES_Init, 0
       
   569 };
       
   570 
       
   571 #endif /* SDL_AUDIO_DRIVER_OPENSLES */
       
   572 
       
   573 /* vi: set ts=4 sw=4 expandtab: */