forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			134 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <kinc/audio2/audio.h>
 | 
						|
 | 
						|
#include <SLES/OpenSLES.h>
 | 
						|
#include <SLES/OpenSLES_Android.h>
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
static kinc_a2_buffer_t a2_buffer;
 | 
						|
 | 
						|
static SLObjectItf engineObject;
 | 
						|
static SLEngineItf engineEngine;
 | 
						|
static SLObjectItf outputMixObject;
 | 
						|
static SLObjectItf bqPlayerObject;
 | 
						|
static SLPlayItf bqPlayerPlay = NULL;
 | 
						|
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
 | 
						|
#define AUDIO_BUFFER_SIZE 1 * 1024
 | 
						|
static int16_t tempBuffer[AUDIO_BUFFER_SIZE];
 | 
						|
 | 
						|
static void copySample(void *buffer) {
 | 
						|
	float left_value = *(float *)&a2_buffer.channels[0][a2_buffer.read_location];
 | 
						|
	float right_value = *(float *)&a2_buffer.channels[1][a2_buffer.read_location];
 | 
						|
	a2_buffer.read_location += 1;
 | 
						|
	if (a2_buffer.read_location >= a2_buffer.data_size) {
 | 
						|
		a2_buffer.read_location = 0;
 | 
						|
	}
 | 
						|
	((int16_t *)buffer)[0] = (int16_t)(left_value * 32767);
 | 
						|
	((int16_t *)buffer)[1] = (int16_t)(right_value * 32767);
 | 
						|
}
 | 
						|
 | 
						|
static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf caller, void *context) {
 | 
						|
	if (kinc_a2_internal_callback(&a2_buffer, AUDIO_BUFFER_SIZE / 2)) {
 | 
						|
		for (int i = 0; i < AUDIO_BUFFER_SIZE; i += 2) {
 | 
						|
			copySample(&tempBuffer[i]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		memset(tempBuffer, 0, sizeof(tempBuffer));
 | 
						|
	}
 | 
						|
	SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, tempBuffer, AUDIO_BUFFER_SIZE * 2);
 | 
						|
}
 | 
						|
 | 
						|
static bool initialized = false;
 | 
						|
 | 
						|
void kinc_a2_init() {
 | 
						|
	if (initialized) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	kinc_a2_internal_init();
 | 
						|
	initialized = true;
 | 
						|
 | 
						|
	a2_buffer.read_location = 0;
 | 
						|
	a2_buffer.write_location = 0;
 | 
						|
	a2_buffer.data_size = 128 * 1024;
 | 
						|
	a2_buffer.channel_count = 2;
 | 
						|
	a2_buffer.channels[0] = (float*)malloc(a2_buffer.data_size * sizeof(float));
 | 
						|
	a2_buffer.channels[1] = (float*)malloc(a2_buffer.data_size * sizeof(float));
 | 
						|
 | 
						|
	SLresult result;
 | 
						|
	result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
 | 
						|
	result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
 | 
						|
	result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
 | 
						|
 | 
						|
	const SLInterfaceID ids[] = {SL_IID_VOLUME};
 | 
						|
	const SLboolean req[] = {SL_BOOLEAN_FALSE};
 | 
						|
	result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
 | 
						|
	result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
 | 
						|
 | 
						|
	SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
 | 
						|
	SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,           2,
 | 
						|
	                               SL_SAMPLINGRATE_44_1,        SL_PCMSAMPLEFORMAT_FIXED_16,
 | 
						|
	                               SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
 | 
						|
	                               SL_BYTEORDER_LITTLEENDIAN};
 | 
						|
	SLDataSource audioSrc = {&loc_bufq, &format_pcm};
 | 
						|
 | 
						|
	SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
 | 
						|
	SLDataSink audioSnk = {&loc_outmix, NULL};
 | 
						|
 | 
						|
	const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
 | 
						|
	const SLboolean req1[] = {SL_BOOLEAN_TRUE};
 | 
						|
	result = (*engineEngine)->CreateAudioPlayer(engineEngine, &(bqPlayerObject), &audioSrc, &audioSnk, 1, ids1, req1);
 | 
						|
	result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
 | 
						|
 | 
						|
	result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &(bqPlayerPlay));
 | 
						|
 | 
						|
	result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(bqPlayerBufferQueue));
 | 
						|
 | 
						|
	result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
 | 
						|
 | 
						|
	result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
 | 
						|
 | 
						|
	memset(tempBuffer, 0, sizeof(tempBuffer));
 | 
						|
	result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, tempBuffer, AUDIO_BUFFER_SIZE * 2);
 | 
						|
}
 | 
						|
 | 
						|
void pauseAudio() {
 | 
						|
	if (bqPlayerPlay == NULL) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
 | 
						|
}
 | 
						|
 | 
						|
void resumeAudio() {
 | 
						|
	if (bqPlayerPlay == NULL) {
 | 
						|
		return;
 | 
						|
	}
 | 
						|
	SLresult result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
 | 
						|
}
 | 
						|
 | 
						|
void kinc_a2_update() {}
 | 
						|
 | 
						|
void kinc_a2_shutdown() {
 | 
						|
	if (bqPlayerObject != NULL) {
 | 
						|
		(*bqPlayerObject)->Destroy(bqPlayerObject);
 | 
						|
		bqPlayerObject = NULL;
 | 
						|
		bqPlayerPlay = NULL;
 | 
						|
		bqPlayerBufferQueue = NULL;
 | 
						|
	}
 | 
						|
	if (outputMixObject != NULL) {
 | 
						|
		(*outputMixObject)->Destroy(outputMixObject);
 | 
						|
		outputMixObject = NULL;
 | 
						|
	}
 | 
						|
	if (engineObject != NULL) {
 | 
						|
		(*engineObject)->Destroy(engineObject);
 | 
						|
		engineObject = NULL;
 | 
						|
		engineEngine = NULL;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
uint32_t kinc_a2_samples_per_second(void) {
 | 
						|
	return 44100;
 | 
						|
}
 |