diff --git a/channels/audin/client/opensles/opensl_io.c b/channels/audin/client/opensles/opensl_io.c index d9e684fe5..f03395227 100644 --- a/channels/audin/client/opensles/opensl_io.c +++ b/channels/audin/client/opensles/opensl_io.c @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -34,114 +34,132 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define CONV16BIT 32768 #define CONVMYFLT (1./32768.) -static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context); +static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void* context); // creates the OpenSL ES audio engine -static SLresult openSLCreateEngine(OPENSL_STREAM *p) +static SLresult openSLCreateEngine(OPENSL_STREAM* p) { - SLresult result; - // create engine - result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); + SLresult result; + // create engine + result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); DEBUG_DVC("engineObject=%p", p->engineObject); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // realize the engine - result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // realize the engine + result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); DEBUG_DVC("Realize=%d", result); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // get the engine interface, which is needed in order to create other objects - result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine)); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // get the engine interface, which is needed in order to create other objects + result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, + &(p->engineEngine)); DEBUG_DVC("engineEngine=%p", p->engineEngine); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // get the volume interface - important, this is optional! - result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_DEVICEVOLUME, &(p->deviceVolume)); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // get the volume interface - important, this is optional! + result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_DEVICEVOLUME, + &(p->deviceVolume)); DEBUG_DVC("deviceVolume=%p", p->deviceVolume); - if(result != SL_RESULT_SUCCESS) + + if (result != SL_RESULT_SUCCESS) { p->deviceVolume = NULL; result = SL_RESULT_SUCCESS; } - engine_end: +engine_end: assert(SL_RESULT_SUCCESS == result); - return result; + return result; } // Open the OpenSL ES device for input -static SLresult openSLRecOpen(OPENSL_STREAM *p){ - - SLresult result; - SLuint32 sr = p->sr; - SLuint32 channels = p->inchannels; - +static SLresult openSLRecOpen(OPENSL_STREAM* p) +{ + SLresult result; + SLuint32 sr = p->sr; + SLuint32 channels = p->inchannels; assert(!p->recorderObject); - if(channels){ + if (channels) + { + switch (sr) + { + case 8000: + sr = SL_SAMPLINGRATE_8; + break; - switch(sr){ + case 11025: + sr = SL_SAMPLINGRATE_11_025; + break; - case 8000: - sr = SL_SAMPLINGRATE_8; - break; - case 11025: - sr = SL_SAMPLINGRATE_11_025; - break; - case 16000: - sr = SL_SAMPLINGRATE_16; - break; - case 22050: - sr = SL_SAMPLINGRATE_22_05; - break; - case 24000: - sr = SL_SAMPLINGRATE_24; - break; - case 32000: - sr = SL_SAMPLINGRATE_32; - break; - case 44100: - sr = SL_SAMPLINGRATE_44_1; - break; - case 48000: - sr = SL_SAMPLINGRATE_48; - break; - case 64000: - sr = SL_SAMPLINGRATE_64; - break; - case 88200: - sr = SL_SAMPLINGRATE_88_2; - break; - case 96000: - sr = SL_SAMPLINGRATE_96; - break; - case 192000: - sr = SL_SAMPLINGRATE_192; - break; - default: - return -1; - } - - // configure audio source - SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, - SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; - SLDataSource audioSrc = {&loc_dev, NULL}; + case 16000: + sr = SL_SAMPLINGRATE_16; + break; - // configure audio sink - int speakers; - if(channels > 1) - speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; - else + case 22050: + sr = SL_SAMPLINGRATE_22_05; + break; + + case 24000: + sr = SL_SAMPLINGRATE_24; + break; + + case 32000: + sr = SL_SAMPLINGRATE_32; + break; + + case 44100: + sr = SL_SAMPLINGRATE_44_1; + break; + + case 48000: + sr = SL_SAMPLINGRATE_48; + break; + + case 64000: + sr = SL_SAMPLINGRATE_64; + break; + + case 88200: + sr = SL_SAMPLINGRATE_88_2; + break; + + case 96000: + sr = SL_SAMPLINGRATE_96; + break; + + case 192000: + sr = SL_SAMPLINGRATE_192; + break; + + default: + return -1; + } + + // configure audio source + SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, + SL_DEFAULTDEVICEID_AUDIOINPUT, NULL + }; + SLDataSource audioSrc = {&loc_dev, NULL}; + // configure audio sink + int speakers; + + if (channels > 1) + speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + else speakers = SL_SPEAKER_FRONT_CENTER; - SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; - SLDataFormat_PCM format_pcm; - + + SLDataLocator_AndroidSimpleBufferQueue loc_bq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; + SLDataFormat_PCM format_pcm; format_pcm.formatType = SL_DATAFORMAT_PCM; format_pcm.numChannels = channels; format_pcm.samplesPerSec = sr; format_pcm.channelMask = speakers; - format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; - + format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; + if (16 == p->bits_per_sample) { format_pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; @@ -155,131 +173,135 @@ static SLresult openSLRecOpen(OPENSL_STREAM *p){ else assert(0); - SLDataSink audioSnk = {&loc_bq, &format_pcm}; - - // create audio recorder - // (requires the RECORD_AUDIO permission) - const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; - const SLboolean req[] = {SL_BOOLEAN_TRUE}; - result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine, - &(p->recorderObject), &audioSrc, &audioSnk, 1, id, req); + SLDataSink audioSnk = {&loc_bq, &format_pcm}; + // create audio recorder + // (requires the RECORD_AUDIO permission) + const SLInterfaceID id[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; + const SLboolean req[] = {SL_BOOLEAN_TRUE}; + result = (*p->engineEngine)->CreateAudioRecorder(p->engineEngine, + &(p->recorderObject), &audioSrc, &audioSnk, 1, id, req); DEBUG_DVC("p->recorderObject=%p", p->recorderObject); assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - // realize the audio recorder - result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // realize the audio recorder + result = (*p->recorderObject)->Realize(p->recorderObject, SL_BOOLEAN_FALSE); DEBUG_DVC("Realize=%d", result); assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - // get the record interface - result = (*p->recorderObject)->GetInterface(p->recorderObject, - SL_IID_RECORD, &(p->recorderRecord)); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // get the record interface + result = (*p->recorderObject)->GetInterface(p->recorderObject, + SL_IID_RECORD, &(p->recorderRecord)); DEBUG_DVC("p->recorderRecord=%p", p->recorderRecord); assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - - // get the buffer queue interface - result = (*p->recorderObject)->GetInterface(p->recorderObject, - SL_IID_ANDROIDSIMPLEBUFFERQUEUE, - &(p->recorderBufferQueue)); - DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue); - assert(!result); - if (SL_RESULT_SUCCESS != result) goto end_recopen; - // register callback on the buffer queue - result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue, - bqRecorderCallback, p); + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // get the buffer queue interface + result = (*p->recorderObject)->GetInterface(p->recorderObject, + SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &(p->recorderBufferQueue)); DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue); assert(!result); - if (SL_RESULT_SUCCESS != result) + + if (SL_RESULT_SUCCESS != result) goto end_recopen; + + // register callback on the buffer queue + result = (*p->recorderBufferQueue)->RegisterCallback(p->recorderBufferQueue, + bqRecorderCallback, p); + DEBUG_DVC("p->recorderBufferQueue=%p", p->recorderBufferQueue); + assert(!result); + + if (SL_RESULT_SUCCESS != result) goto end_recopen; - end_recopen: - return result; - } - else return SL_RESULT_SUCCESS; - - + end_recopen: + return result; + } + else return SL_RESULT_SUCCESS; } // close the OpenSL IO and destroy the audio engine -static void openSLDestroyEngine(OPENSL_STREAM *p) +static void openSLDestroyEngine(OPENSL_STREAM* p) { DEBUG_DVC("p=%p", p); - // destroy audio recorder object, and invalidate all associated interfaces - if (p->recorderObject != NULL) { - (*p->recorderObject)->Destroy(p->recorderObject); - p->recorderObject = NULL; - p->recorderRecord = NULL; - p->recorderBufferQueue = NULL; - } - - // destroy engine object, and invalidate all associated interfaces - if (p->engineObject != NULL) { - (*p->engineObject)->Destroy(p->engineObject); - p->engineObject = NULL; - p->engineEngine = NULL; - } + // destroy audio recorder object, and invalidate all associated interfaces + if (p->recorderObject != NULL) + { + (*p->recorderObject)->Destroy(p->recorderObject); + p->recorderObject = NULL; + p->recorderRecord = NULL; + p->recorderBufferQueue = NULL; + } + // destroy engine object, and invalidate all associated interfaces + if (p->engineObject != NULL) + { + (*p->engineObject)->Destroy(p->engineObject); + p->engineObject = NULL; + p->engineEngine = NULL; + } } -// open the android audio device for input -OPENSL_STREAM *android_OpenRecDevice(char *name, int sr, int inchannels, - int bufferframes, int bits_per_sample) +// open the android audio device for input +OPENSL_STREAM* android_OpenRecDevice(char* name, int sr, int inchannels, + int bufferframes, int bits_per_sample) { - - OPENSL_STREAM *p; - p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM),1); - if (!p) - return NULL; + OPENSL_STREAM* p; + p = (OPENSL_STREAM*) calloc(sizeof(OPENSL_STREAM), 1); - p->inchannels = inchannels; - p->sr = sr; + if (!p) + return NULL; + + p->inchannels = inchannels; + p->sr = sr; p->queue = Queue_New(TRUE, -1, -1); p->buffersize = bufferframes; p->bits_per_sample = bits_per_sample; if ((p->bits_per_sample != 8) && (p->bits_per_sample != 16)) { - android_CloseRecDevice(p); + android_CloseRecDevice(p); return NULL; } - - if(openSLCreateEngine(p) != SL_RESULT_SUCCESS) - { - android_CloseRecDevice(p); - return NULL; - } - if(openSLRecOpen(p) != SL_RESULT_SUCCESS) + if (openSLCreateEngine(p) != SL_RESULT_SUCCESS) { - android_CloseRecDevice(p); - return NULL; - } + android_CloseRecDevice(p); + return NULL; + } - return p; + if (openSLRecOpen(p) != SL_RESULT_SUCCESS) + { + android_CloseRecDevice(p); + return NULL; + } + + return p; } // close the android audio device -void android_CloseRecDevice(OPENSL_STREAM *p) +void android_CloseRecDevice(OPENSL_STREAM* p) { DEBUG_DVC("p=%p", p); - if (p == NULL) - return; + if (p == NULL) + return; if (p->queue) { while (Queue_Count(p->queue) > 0) { - queue_element *e = Queue_Dequeue(p->queue); + queue_element* e = Queue_Dequeue(p->queue); free(e->data); free(e); } + Queue_Free(p->queue); } @@ -295,52 +317,47 @@ void android_CloseRecDevice(OPENSL_STREAM *p) free(p->prep); } - openSLDestroyEngine(p); - - free(p); + openSLDestroyEngine(p); + free(p); } // this callback handler is called every time a buffer finishes recording -void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void* context) { - queue_element *e; - - OPENSL_STREAM *p = (OPENSL_STREAM *) context; - + queue_element* e; + OPENSL_STREAM* p = (OPENSL_STREAM*) context; DEBUG_DVC("p=%p", p); - assert(p); assert(p->next); assert(p->prep); assert(p->queue); - e = calloc(1, sizeof(queue_element)); + if (!e) return; + e->data = calloc(p->buffersize, p->bits_per_sample / 8); + if (!e->data) { free(e); return; } - e->size = p->buffersize * p->bits_per_sample / 8; + e->size = p->buffersize * p->bits_per_sample / 8; Queue_Enqueue(p->queue, p->next); p->next = p->prep; p->prep = e; - - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - e->data, e->size); - + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + e->data, e->size); } - -// gets a buffer of size samples from the device -int android_RecIn(OPENSL_STREAM *p,short *buffer,int size) -{ - queue_element *e; - int rc; - DWORD status; +// gets a buffer of size samples from the device +int android_RecIn(OPENSL_STREAM* p, short* buffer, int size) +{ + queue_element* e; + int rc; + DWORD status; assert(p); assert(buffer); assert(size > 0); @@ -349,35 +366,33 @@ int android_RecIn(OPENSL_STREAM *p,short *buffer,int size) if (!p->prep) { p->prep = calloc(1, sizeof(queue_element)); - p->prep->data = calloc(p->buffersize, p->bits_per_sample / 8); p->prep->size = p->buffersize * p->bits_per_sample / 8; - p->next = calloc(1, sizeof(queue_element)); p->next->data = calloc(p->buffersize, p->bits_per_sample / 8); p->next->size = p->buffersize * p->bits_per_sample / 8; - - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - p->next->data, p->next->size); - (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, - p->prep->data, p->prep->size); - - (*p->recorderRecord)->SetRecordState(p->recorderRecord, SL_RECORDSTATE_RECORDING); + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + p->next->data, p->next->size); + (*p->recorderBufferQueue)->Enqueue(p->recorderBufferQueue, + p->prep->data, p->prep->size); + (*p->recorderRecord)->SetRecordState(p->recorderRecord, + SL_RECORDSTATE_RECORDING); } /* Wait for queue to be filled... */ if (!Queue_Count(p->queue)) - { - status = WaitForSingleObject(p->queue->event, INFINITE); - if (status == WAIT_FAILED) - { - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError()); - return -1; - } - } + { + status = WaitForSingleObject(p->queue->event, INFINITE); + if (status == WAIT_FAILED) + { + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", GetLastError()); + return -1; + } + } e = Queue_Dequeue(p->queue); + if (!e) { WLog_ERR(TAG, "[ERROR] got e=%p from queue", e); @@ -387,11 +402,9 @@ int android_RecIn(OPENSL_STREAM *p,short *buffer,int size) rc = (e->size < size) ? e->size : size; assert(size == e->size); assert(p->buffersize * p->bits_per_sample / 8 == size); - memcpy(buffer, e->data, rc); free(e->data); free(e); - - return rc; + return rc; } diff --git a/channels/audin/client/opensles/opensl_io.h b/channels/audin/client/opensles/opensl_io.h index e76cd0664..7d8d33f22 100644 --- a/channels/audin/client/opensles/opensl_io.h +++ b/channels/audin/client/opensles/opensl_io.h @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -36,6 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include + #include #ifdef __cplusplus @@ -45,46 +47,48 @@ extern "C" { typedef struct { size_t size; - void *data; + void* data; } queue_element; -typedef struct opensl_stream { - // engine interfaces - SLObjectItf engineObject; - SLEngineItf engineEngine; +typedef struct opensl_stream +{ + // engine interfaces + SLObjectItf engineObject; + SLEngineItf engineEngine; // device interfaces SLDeviceVolumeItf deviceVolume; - // recorder interfaces - SLObjectItf recorderObject; - SLRecordItf recorderRecord; - SLAndroidSimpleBufferQueueItf recorderBufferQueue; + // recorder interfaces + SLObjectItf recorderObject; + SLRecordItf recorderRecord; + SLAndroidSimpleBufferQueueItf recorderBufferQueue; - unsigned int inchannels; - unsigned int sr; + unsigned int inchannels; + unsigned int sr; unsigned int buffersize; unsigned int bits_per_sample; - wQueue *queue; - queue_element *prep; - queue_element *next; + wQueue* queue; + queue_element* prep; + queue_element* next; } OPENSL_STREAM; - /* - Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size - in frames. Returns a handle to the OpenSL stream - */ - OPENSL_STREAM* android_OpenRecDevice(char *name, int sr, int inchannels, - int bufferframes, int bits_per_sample); - /* - Close the audio device - */ - void android_CloseRecDevice(OPENSL_STREAM *p); - /* - Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read. - */ - int android_RecIn(OPENSL_STREAM *p, short *buffer,int size); +/* +Open the audio device with a given sampling rate (sr), input and output channels and IO buffer size +in frames. Returns a handle to the OpenSL stream +*/ +FREERDP_LOCAL OPENSL_STREAM* android_OpenRecDevice(char* name, int sr, + int inchannels, + int bufferframes, int bits_per_sample); +/* +Close the audio device +*/ +FREERDP_LOCAL void android_CloseRecDevice(OPENSL_STREAM* p); +/* +Read a buffer from the OpenSL stream *p, of size samples. Returns the number of samples read. +*/ +FREERDP_LOCAL int android_RecIn(OPENSL_STREAM* p, short* buffer, int size); #ifdef __cplusplus }; #endif diff --git a/channels/rdpsnd/client/opensles/opensl_io.c b/channels/rdpsnd/client/opensles/opensl_io.c index 282268e32..033232f4a 100644 --- a/channels/rdpsnd/client/opensles/opensl_io.c +++ b/channels/rdpsnd/client/opensles/opensl_io.c @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -34,203 +34,238 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define CONV16BIT 32768 #define CONVMYFLT (1./32768.) -static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context); +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context); // creates the OpenSL ES audio engine -static SLresult openSLCreateEngine(OPENSL_STREAM *p) +static SLresult openSLCreateEngine(OPENSL_STREAM* p) { - SLresult result; - // create engine - result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); + SLresult result; + // create engine + result = slCreateEngine(&(p->engineObject), 0, NULL, 0, NULL, NULL); DEBUG_SND("engineObject=%p", p->engineObject); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // realize the engine - result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // realize the engine + result = (*p->engineObject)->Realize(p->engineObject, SL_BOOLEAN_FALSE); DEBUG_SND("Realize=%d", result); - if(result != SL_RESULT_SUCCESS) goto engine_end; - // get the engine interface, which is needed in order to create other objects - result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, &(p->engineEngine)); + if (result != SL_RESULT_SUCCESS) goto engine_end; + + // get the engine interface, which is needed in order to create other objects + result = (*p->engineObject)->GetInterface(p->engineObject, SL_IID_ENGINE, + &(p->engineEngine)); DEBUG_SND("engineEngine=%p", p->engineEngine); - if(result != SL_RESULT_SUCCESS) goto engine_end; - engine_end: - return result; + if (result != SL_RESULT_SUCCESS) goto engine_end; + +engine_end: + return result; } // opens the OpenSL ES device for output -static SLresult openSLPlayOpen(OPENSL_STREAM *p) +static SLresult openSLPlayOpen(OPENSL_STREAM* p) { - SLresult result; - SLuint32 sr = p->sr; - SLuint32 channels = p->outchannels; - + SLresult result; + SLuint32 sr = p->sr; + SLuint32 channels = p->outchannels; assert(p->engineObject); assert(p->engineEngine); - if(channels){ - // configure audio source - SLDataLocator_AndroidSimpleBufferQueue loc_bufq = + if (channels) + { + // configure audio source + SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, p->queuesize }; - switch(sr){ + switch (sr) + { + case 8000: + sr = SL_SAMPLINGRATE_8; + break; - case 8000: - sr = SL_SAMPLINGRATE_8; - break; - case 11025: - sr = SL_SAMPLINGRATE_11_025; - break; - case 16000: - sr = SL_SAMPLINGRATE_16; - break; - case 22050: - sr = SL_SAMPLINGRATE_22_05; - break; - case 24000: - sr = SL_SAMPLINGRATE_24; - break; - case 32000: - sr = SL_SAMPLINGRATE_32; - break; - case 44100: - sr = SL_SAMPLINGRATE_44_1; - break; - case 48000: - sr = SL_SAMPLINGRATE_48; - break; - case 64000: - sr = SL_SAMPLINGRATE_64; - break; - case 88200: - sr = SL_SAMPLINGRATE_88_2; - break; - case 96000: - sr = SL_SAMPLINGRATE_96; - break; - case 192000: - sr = SL_SAMPLINGRATE_192; - break; - default: - return -1; - } - - const SLInterfaceID ids[] = {SL_IID_VOLUME}; - const SLboolean req[] = {SL_BOOLEAN_FALSE}; - result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, &(p->outputMixObject), 1, ids, req); + case 11025: + sr = SL_SAMPLINGRATE_11_025; + break; + + case 16000: + sr = SL_SAMPLINGRATE_16; + break; + + case 22050: + sr = SL_SAMPLINGRATE_22_05; + break; + + case 24000: + sr = SL_SAMPLINGRATE_24; + break; + + case 32000: + sr = SL_SAMPLINGRATE_32; + break; + + case 44100: + sr = SL_SAMPLINGRATE_44_1; + break; + + case 48000: + sr = SL_SAMPLINGRATE_48; + break; + + case 64000: + sr = SL_SAMPLINGRATE_64; + break; + + case 88200: + sr = SL_SAMPLINGRATE_88_2; + break; + + case 96000: + sr = SL_SAMPLINGRATE_96; + break; + + case 192000: + sr = SL_SAMPLINGRATE_192; + break; + + default: + return -1; + } + + const SLInterfaceID ids[] = {SL_IID_VOLUME}; + const SLboolean req[] = {SL_BOOLEAN_FALSE}; + result = (*p->engineEngine)->CreateOutputMix(p->engineEngine, + &(p->outputMixObject), 1, ids, req); DEBUG_SND("engineEngine=%p", p->engineEngine); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // realize the output mix - result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // realize the output mix + result = (*p->outputMixObject)->Realize(p->outputMixObject, SL_BOOLEAN_FALSE); DEBUG_SND("Realize=%d", result); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - - int speakers; - if(channels > 1) - speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; - else speakers = SL_SPEAKER_FRONT_CENTER; - SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM,channels, sr, - SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, - speakers, SL_BYTEORDER_LITTLEENDIAN}; - SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + if (result != SL_RESULT_SUCCESS) goto end_openaudio; - // configure audio sink - SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject}; - SLDataSink audioSnk = {&loc_outmix, NULL}; + int speakers; - // create audio player - const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME}; - const SLboolean req1[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; - result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine, - &(p->bqPlayerObject), &audioSrc, &audioSnk, 2, ids1, req1); + if (channels > 1) + speakers = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + else speakers = SL_SPEAKER_FRONT_CENTER; + + SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, channels, sr, + SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, + speakers, SL_BYTEORDER_LITTLEENDIAN + }; + SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + // configure audio sink + SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, p->outputMixObject}; + SLDataSink audioSnk = {&loc_outmix, NULL}; + // create audio player + const SLInterfaceID ids1[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME}; + const SLboolean req1[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + result = (*p->engineEngine)->CreateAudioPlayer(p->engineEngine, + &(p->bqPlayerObject), &audioSrc, &audioSnk, 2, ids1, req1); DEBUG_SND("bqPlayerObject=%p", p->bqPlayerObject); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // realize the player - result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // realize the player + result = (*p->bqPlayerObject)->Realize(p->bqPlayerObject, SL_BOOLEAN_FALSE); DEBUG_SND("Realize=%d", result); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // get the play interface - result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, &(p->bqPlayerPlay)); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the play interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_PLAY, + &(p->bqPlayerPlay)); DEBUG_SND("bqPlayerPlay=%p", p->bqPlayerPlay); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // get the volume interface - result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, &(p->bqPlayerVolume)); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the volume interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_VOLUME, + &(p->bqPlayerVolume)); DEBUG_SND("bqPlayerVolume=%p", p->bqPlayerVolume); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // get the buffer queue interface - result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, - &(p->bqPlayerBufferQueue)); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // get the buffer queue interface + result = (*p->bqPlayerObject)->GetInterface(p->bqPlayerObject, + SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &(p->bqPlayerBufferQueue)); DEBUG_SND("bqPlayerBufferQueue=%p", p->bqPlayerBufferQueue); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // register callback on the buffer queue - result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, bqPlayerCallback, p); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // register callback on the buffer queue + result = (*p->bqPlayerBufferQueue)->RegisterCallback(p->bqPlayerBufferQueue, + bqPlayerCallback, p); DEBUG_SND("bqPlayerCallback=%p", p->bqPlayerCallback); assert(!result); - if(result != SL_RESULT_SUCCESS) goto end_openaudio; - // set the player's state to playing - result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, SL_PLAYSTATE_PLAYING); + if (result != SL_RESULT_SUCCESS) goto end_openaudio; + + // set the player's state to playing + result = (*p->bqPlayerPlay)->SetPlayState(p->bqPlayerPlay, + SL_PLAYSTATE_PLAYING); DEBUG_SND("SetPlayState=%d", result); assert(!result); - - end_openaudio: + end_openaudio: assert(!result); - return result; - } - return SL_RESULT_SUCCESS; + return result; + } + + return SL_RESULT_SUCCESS; } // close the OpenSL IO and destroy the audio engine -static void openSLDestroyEngine(OPENSL_STREAM *p){ +static void openSLDestroyEngine(OPENSL_STREAM* p) +{ + // destroy buffer queue audio player object, and invalidate all associated interfaces + if (p->bqPlayerObject != NULL) + { + (*p->bqPlayerObject)->Destroy(p->bqPlayerObject); + p->bqPlayerObject = NULL; + p->bqPlayerVolume = NULL; + p->bqPlayerPlay = NULL; + p->bqPlayerBufferQueue = NULL; + p->bqPlayerEffectSend = NULL; + } - // destroy buffer queue audio player object, and invalidate all associated interfaces - if (p->bqPlayerObject != NULL) { - (*p->bqPlayerObject)->Destroy(p->bqPlayerObject); - p->bqPlayerObject = NULL; - p->bqPlayerVolume = NULL; - p->bqPlayerPlay = NULL; - p->bqPlayerBufferQueue = NULL; - p->bqPlayerEffectSend = NULL; - } - - // destroy output mix object, and invalidate all associated interfaces - if (p->outputMixObject != NULL) { - (*p->outputMixObject)->Destroy(p->outputMixObject); - p->outputMixObject = NULL; - } - - // destroy engine object, and invalidate all associated interfaces - if (p->engineObject != NULL) { - (*p->engineObject)->Destroy(p->engineObject); - p->engineObject = NULL; - p->engineEngine = NULL; - } + // destroy output mix object, and invalidate all associated interfaces + if (p->outputMixObject != NULL) + { + (*p->outputMixObject)->Destroy(p->outputMixObject); + p->outputMixObject = NULL; + } + // destroy engine object, and invalidate all associated interfaces + if (p->engineObject != NULL) + { + (*p->engineObject)->Destroy(p->engineObject); + p->engineObject = NULL; + p->engineEngine = NULL; + } } // open the android audio device for and/or output -OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes){ - OPENSL_STREAM *p; - p = (OPENSL_STREAM *) calloc(sizeof(OPENSL_STREAM), 1); +OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels, + int bufferframes) +{ + OPENSL_STREAM* p; + p = (OPENSL_STREAM*) calloc(sizeof(OPENSL_STREAM), 1); + if (!p) return NULL; @@ -238,19 +273,20 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes p->outchannels = outchannels; p->sr = sr; - if(openSLCreateEngine(p) != SL_RESULT_SUCCESS) + if (openSLCreateEngine(p) != SL_RESULT_SUCCESS) { android_CloseAudioDevice(p); return NULL; } - if(openSLPlayOpen(p) != SL_RESULT_SUCCESS) + if (openSLPlayOpen(p) != SL_RESULT_SUCCESS) { android_CloseAudioDevice(p); return NULL; } p->queue = Queue_New(TRUE, -1, -1); + if (!p->queue) { android_CloseAudioDevice(p); @@ -261,107 +297,120 @@ OPENSL_STREAM *android_OpenAudioDevice(int sr, int outchannels, int bufferframes } // close the android audio device -void android_CloseAudioDevice(OPENSL_STREAM *p){ +void android_CloseAudioDevice(OPENSL_STREAM* p) +{ + if (p == NULL) + return; - if (p == NULL) - return; + openSLDestroyEngine(p); - openSLDestroyEngine(p); if (p->queue) Queue_Free(p->queue); - free(p); + free(p); } // this callback handler is called every time a buffer finishes playing -void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void* context) { - OPENSL_STREAM *p = (OPENSL_STREAM *) context; - + OPENSL_STREAM* p = (OPENSL_STREAM*) context; assert(p); assert(p->queue); - - void *data = Queue_Dequeue(p->queue); + void* data = Queue_Dequeue(p->queue); free(data); } // puts a buffer of size samples to the device -int android_AudioOut(OPENSL_STREAM *p, const short *buffer,int size) +int android_AudioOut(OPENSL_STREAM* p, const short* buffer, int size) { assert(p); assert(buffer); assert(size > 0); /* Assure, that the queue is not full. */ - if (p->queuesize <= Queue_Count(p->queue) && WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED) - { - DEBUG_SND("WaitForSingleObject failed!"); - return -1; - } + if (p->queuesize <= Queue_Count(p->queue) + && WaitForSingleObject(p->queue->event, INFINITE) == WAIT_FAILED) + { + DEBUG_SND("WaitForSingleObject failed!"); + return -1; + } + + void* data = calloc(size, sizeof(short)); - void *data = calloc(size, sizeof(short)); if (!data) { DEBUG_SND("unable to allocate a buffer"); return -1; } + memcpy(data, buffer, size * sizeof(short)); Queue_Enqueue(p->queue, data); - (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, - data, sizeof(short) * size); - + (*p->bqPlayerBufferQueue)->Enqueue(p->bqPlayerBufferQueue, + data, sizeof(short) * size); return size; } -int android_GetOutputMute(OPENSL_STREAM *p) { +int android_GetOutputMute(OPENSL_STREAM* p) +{ SLboolean mute; - assert(p); assert(p->bqPlayerVolume); - SLresult rc = (*p->bqPlayerVolume)->GetMute(p->bqPlayerVolume, &mute); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return SL_BOOLEAN_FALSE; return mute; } -void android_SetOutputMute(OPENSL_STREAM *p, BOOL _mute) { +BOOL android_SetOutputMute(OPENSL_STREAM* p, BOOL _mute) +{ SLboolean mute = _mute; - assert(p); assert(p->bqPlayerVolume); - SLresult rc = (*p->bqPlayerVolume)->SetMute(p->bqPlayerVolume, mute); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return FALSE; + + return TRUE; } -int android_GetOutputVolume(OPENSL_STREAM *p){ +int android_GetOutputVolume(OPENSL_STREAM* p) +{ SLmillibel level; - assert(p); assert(p->bqPlayerVolume); - SLresult rc = (*p->bqPlayerVolume)->GetVolumeLevel(p->bqPlayerVolume, &level); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return 0; return level; } -int android_GetOutputVolumeMax(OPENSL_STREAM *p){ +int android_GetOutputVolumeMax(OPENSL_STREAM* p) +{ SLmillibel level; - assert(p); assert(p->bqPlayerVolume); + SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, + &level); - SLresult rc = (*p->bqPlayerVolume)->GetMaxVolumeLevel(p->bqPlayerVolume, &level); - assert(SL_RESULT_SUCCESS == rc); + if (SL_RESULT_SUCCESS != rc) + return 0; return level; } -void android_SetOutputVolume(OPENSL_STREAM *p, int level){ +BOOL android_SetOutputVolume(OPENSL_STREAM* p, int level) +{ SLresult rc = (*p->bqPlayerVolume)->SetVolumeLevel(p->bqPlayerVolume, level); - assert(SL_RESULT_SUCCESS == rc); + + if (SL_RESULT_SUCCESS != rc) + return FALSE; + + return TRUE; } diff --git a/channels/rdpsnd/client/opensles/opensl_io.h b/channels/rdpsnd/client/opensles/opensl_io.h index 3a6762ffd..00e4f12c1 100644 --- a/channels/rdpsnd/client/opensles/opensl_io.h +++ b/channels/rdpsnd/client/opensles/opensl_io.h @@ -6,14 +6,14 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -35,70 +35,75 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include + #ifdef __cplusplus extern "C" { #endif -typedef struct opensl_stream { - // engine interfaces - SLObjectItf engineObject; - SLEngineItf engineEngine; +typedef struct opensl_stream +{ + // engine interfaces + SLObjectItf engineObject; + SLEngineItf engineEngine; - // output mix interfaces - SLObjectItf outputMixObject; + // output mix interfaces + SLObjectItf outputMixObject; - // buffer queue player interfaces - SLObjectItf bqPlayerObject; - SLPlayItf bqPlayerPlay; + // buffer queue player interfaces + SLObjectItf bqPlayerObject; + SLPlayItf bqPlayerPlay; SLVolumeItf bqPlayerVolume; - SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; - SLEffectSendItf bqPlayerEffectSend; + SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; + SLEffectSendItf bqPlayerEffectSend; - unsigned int outchannels; - unsigned int sr; + unsigned int outchannels; + unsigned int sr; unsigned int queuesize; - wQueue *queue; + wQueue* queue; } OPENSL_STREAM; - /* - Open the audio device with a given sampling rate (sr), output channels and IO buffer size - in frames. Returns a handle to the OpenSL stream - */ - OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels, int bufferframes); - /* - Close the audio device - */ - void android_CloseAudioDevice(OPENSL_STREAM *p); - /* - Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written. - */ - int android_AudioOut(OPENSL_STREAM *p, const short *buffer, int size); - /* - * Set the volume input level. - */ - void android_SetInputVolume(OPENSL_STREAM *p, int level); - /* - * Get the current output mute setting. - */ - int android_GetOutputMute(OPENSL_STREAM *p); - /* - * Change the current output mute setting. - */ - void android_SetOutputMute(OPENSL_STREAM *p, BOOL mute); - /* - * Get the current output volume level. - */ - int android_GetOutputVolume(OPENSL_STREAM *p); - /* - * Get the maximum output volume level. - */ - int android_GetOutputVolumeMax(OPENSL_STREAM *p); +/* +Open the audio device with a given sampling rate (sr), output channels and IO buffer size +in frames. Returns a handle to the OpenSL stream +*/ +FREERDP_LOCAL OPENSL_STREAM* android_OpenAudioDevice(int sr, int outchannels, + int bufferframes); +/* +Close the audio device +*/ +FREERDP_LOCAL void android_CloseAudioDevice(OPENSL_STREAM* p); +/* +Write a buffer to the OpenSL stream *p, of size samples. Returns the number of samples written. +*/ +FREERDP_LOCAL int android_AudioOut(OPENSL_STREAM* p, const short* buffer, + int size); +/* + * Set the volume input level. + */ +FREERDP_LOCAL void android_SetInputVolume(OPENSL_STREAM* p, int level); +/* + * Get the current output mute setting. + */ +FREERDP_LOCAL int android_GetOutputMute(OPENSL_STREAM* p); +/* + * Change the current output mute setting. + */ +FREERDP_LOCAL BOOL android_SetOutputMute(OPENSL_STREAM* p, BOOL mute); +/* + * Get the current output volume level. + */ +FREERDP_LOCAL int android_GetOutputVolume(OPENSL_STREAM* p); +/* + * Get the maximum output volume level. + */ +FREERDP_LOCAL int android_GetOutputVolumeMax(OPENSL_STREAM* p); - /* - * Set the volume output level. - */ - void android_SetOutputVolume(OPENSL_STREAM *p, int level); +/* + * Set the volume output level. + */ +FREERDP_LOCAL BOOL android_SetOutputVolume(OPENSL_STREAM* p, int level); #ifdef __cplusplus }; #endif diff --git a/channels/rdpsnd/client/opensles/rdpsnd_opensles.c b/channels/rdpsnd/client/opensles/rdpsnd_opensles.c index 39b26f6c3..bbc5de28d 100644 --- a/channels/rdpsnd/client/opensles/rdpsnd_opensles.c +++ b/channels/rdpsnd/client/opensles/rdpsnd_opensles.c @@ -53,7 +53,7 @@ struct rdpsnd_opensles_plugin int block_size; char* device_name; - OPENSL_STREAM *stream; + OPENSL_STREAM* stream; UINT32 volume; @@ -68,10 +68,8 @@ static int rdpsnd_opensles_volume_to_millibel(unsigned short level, int max) const int min = SL_MILLIBEL_MIN; const int step = max - min; const int rc = (level * step / 0xFFFF) + min; - DEBUG_SND("level=%d, min=%d, max=%d, step=%d, result=%d", - level, min, max, step, rc); - + level, min, max, step, rc); return rc; } @@ -80,14 +78,12 @@ static unsigned short rdpsnd_opensles_millibel_to_volume(int millibel, int max) const int min = SL_MILLIBEL_MIN; const int range = max - min; const int rc = ((millibel - min) * 0xFFFF + range / 2 + 1) / range; - DEBUG_SND("millibel=%d, min=%d, max=%d, range=%d, result=%d", - millibel, min, max, range, rc); - + millibel, min, max, range, rc); return rc; } -static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl) +static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin* hdl) { bool rc = true; @@ -97,6 +93,7 @@ static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl) { if (!hdl->dsp_context) rc = false; + if (!hdl->stream) rc = false; } @@ -105,11 +102,12 @@ static bool rdpsnd_opensles_check_handle(const rdpsndopenslesPlugin *hdl) } static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device, - UINT32 volume); + UINT32 volume); static int rdpsnd_opensles_set_params(rdpsndopenslesPlugin* opensles) { DEBUG_SND("opensles=%p", opensles); + if (!rdpsnd_opensles_check_handle(opensles)) return 0; @@ -117,25 +115,22 @@ static int rdpsnd_opensles_set_params(rdpsndopenslesPlugin* opensles) android_CloseAudioDevice(opensles->stream); opensles->stream = android_OpenAudioDevice( - opensles->rate, opensles->channels, 20); - + opensles->rate, opensles->channels, 20); return 0; } static BOOL rdpsnd_opensles_set_format(rdpsndDevicePlugin* device, - AUDIO_FORMAT* format, int latency) + AUDIO_FORMAT* format, int latency) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; rdpsnd_opensles_check_handle(opensles); - DEBUG_SND("opensles=%p format=%p, latency=%d", opensles, format, latency); if (format) { DEBUG_SND("format=%d, cbsize=%d, samples=%d, bits=%d, channels=%d, align=%d", - format->wFormatTag, format->cbSize, format->nSamplesPerSec, - format->wBitsPerSample, format->nChannels, format->nBlockAlign); - + format->wFormatTag, format->cbSize, format->nSamplesPerSec, + format->wBitsPerSample, format->nChannels, format->nBlockAlign); opensles->rate = format->nSamplesPerSec; opensles->channels = format->nChannels; opensles->format = format->wFormatTag; @@ -144,22 +139,21 @@ static BOOL rdpsnd_opensles_set_format(rdpsndDevicePlugin* device, } opensles->latency = latency; - return (rdpsnd_opensles_set_params(opensles) == 0); } static BOOL rdpsnd_opensles_open(rdpsndDevicePlugin* device, - AUDIO_FORMAT* format, int latency) + AUDIO_FORMAT* format, int latency) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p format=%p, latency=%d, rate=%d", - opensles, format, latency, opensles->rate); - + opensles, format, latency, opensles->rate); + if (rdpsnd_opensles_check_handle(opensles)) return TRUE; - opensles->stream = android_OpenAudioDevice(opensles->rate, opensles->channels, 20); + opensles->stream = android_OpenAudioDevice(opensles->rate, opensles->channels, + 20); assert(opensles->stream); if (!opensles->stream) @@ -174,9 +168,9 @@ static BOOL rdpsnd_opensles_open(rdpsndDevicePlugin* device, static void rdpsnd_opensles_close(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p", opensles); - if( !rdpsnd_opensles_check_handle(opensles)) + + if (!rdpsnd_opensles_check_handle(opensles)) return; android_CloseAudioDevice(opensles->stream); @@ -186,51 +180,46 @@ static void rdpsnd_opensles_close(rdpsndDevicePlugin* device) static void rdpsnd_opensles_free(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p", opensles); assert(opensles); - assert(opensles->device_name); free(opensles->device_name); - assert(opensles->dsp_context); freerdp_dsp_context_free(opensles->dsp_context); - free(opensles); } static BOOL rdpsnd_opensles_format_supported(rdpsndDevicePlugin* device, - AUDIO_FORMAT* format) + AUDIO_FORMAT* format) { - rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("format=%d, cbsize=%d, samples=%d, bits=%d, channels=%d, align=%d", - format->wFormatTag, format->cbSize, format->nSamplesPerSec, - format->wBitsPerSample, format->nChannels, format->nBlockAlign); - - assert(opensles); + format->wFormatTag, format->cbSize, format->nSamplesPerSec, + format->wBitsPerSample, format->nChannels, format->nBlockAlign); + assert(device); assert(format); switch (format->wFormatTag) { case WAVE_FORMAT_PCM: if (format->cbSize == 0 && - format->nSamplesPerSec <= 48000 && - (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && - (format->nChannels == 1 || format->nChannels == 2)) + format->nSamplesPerSec <= 48000 && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels == 1 || format->nChannels == 2)) { return TRUE; } + break; case WAVE_FORMAT_ADPCM: case WAVE_FORMAT_DVI_ADPCM: if (format->nSamplesPerSec <= 48000 && - format->wBitsPerSample == 4 && - (format->nChannels == 1 || format->nChannels == 2)) + format->wBitsPerSample == 4 && + (format->nChannels == 1 || format->nChannels == 2)) { return TRUE; } + break; case WAVE_FORMAT_ALAW: @@ -246,7 +235,6 @@ static BOOL rdpsnd_opensles_format_supported(rdpsndDevicePlugin* device, static UINT32 rdpsnd_opensles_get_volume(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p", opensles); assert(opensles); @@ -263,31 +251,32 @@ static UINT32 rdpsnd_opensles_get_volume(rdpsndDevicePlugin* device) opensles->volume = (vol << 16) | (vol & 0xFFFF); } } - + return opensles->volume; } static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device, - UINT32 value) + UINT32 value) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p, value=%d", opensles, value); assert(opensles); - opensles->volume = value; if (opensles->stream) { if (0 == opensles->volume) - android_SetOutputMute(opensles->stream, true); + return android_SetOutputMute(opensles->stream, true); else { const int max = android_GetOutputVolumeMax(opensles->stream); const int vol = rdpsnd_opensles_volume_to_millibel(value & 0xFFFF, max); - android_SetOutputMute(opensles->stream, false); - android_SetOutputVolume(opensles->stream, vol); + if (!android_SetOutputMute(opensles->stream, false)) + return FALSE; + + if (!android_SetOutputVolume(opensles->stream, vol)) + return FALSE; } } @@ -295,53 +284,49 @@ static BOOL rdpsnd_opensles_set_volume(rdpsndDevicePlugin* device, } static void rdpsnd_opensles_play(rdpsndDevicePlugin* device, - BYTE *data, int size) + BYTE* data, int size) { union { - BYTE *b; - short *s; + BYTE* b; + short* s; } src; int ret; rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - DEBUG_SND("opensles=%p, data=%p, size=%d", opensles, data, size); + if (!rdpsnd_opensles_check_handle(opensles)) return; if (opensles->format == WAVE_FORMAT_ADPCM) { DEBUG_SND("dsp_context=%p, channels=%d, block_size=%d", - opensles->dsp_context, opensles->channels, opensles->block_size); - + opensles->dsp_context, opensles->channels, opensles->block_size); opensles->dsp_context->decode_ms_adpcm(opensles->dsp_context, - data, size, opensles->channels, opensles->block_size); - + data, size, opensles->channels, opensles->block_size); size = opensles->dsp_context->adpcm_size; src.b = opensles->dsp_context->adpcm_buffer; } else if (opensles->format == WAVE_FORMAT_DVI_ADPCM) { DEBUG_SND("dsp_context=%p, channels=%d, block_size=%d", - opensles->dsp_context, opensles->channels, opensles->block_size); - + opensles->dsp_context, opensles->channels, opensles->block_size); opensles->dsp_context->decode_ima_adpcm(opensles->dsp_context, - data, size, opensles->channels, opensles->block_size); - + data, size, opensles->channels, opensles->block_size); size = opensles->dsp_context->adpcm_size; src.b = opensles->dsp_context->adpcm_buffer; } else - { + { src.b = data; - } + } DEBUG_SND("size=%d, src=%p", size, src.b); assert(0 == size % 2); assert(size > 0); assert(src.b); - ret = android_AudioOut(opensles->stream, src.s, size / 2); + if (ret < 0) WLog_ERR(TAG, "android_AudioOut failed (%d)", ret); } @@ -350,34 +335,33 @@ static void rdpsnd_opensles_start(rdpsndDevicePlugin* device) { rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; rdpsnd_opensles_check_handle(opensles); - DEBUG_SND("opensles=%p", opensles); } static COMMAND_LINE_ARGUMENT_A rdpsnd_opensles_args[] = { - { "dev", COMMAND_LINE_VALUE_REQUIRED, "", - NULL, NULL, -1, NULL, "device" }, + { + "dev", COMMAND_LINE_VALUE_REQUIRED, "", + NULL, NULL, -1, NULL, "device" + }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device, - ADDIN_ARGV* args) + ADDIN_ARGV* args) { int status; DWORD flags; COMMAND_LINE_ARGUMENT_A* arg; rdpsndopenslesPlugin* opensles = (rdpsndopenslesPlugin*) device; - assert(opensles); assert(args); - DEBUG_SND("opensles=%p, args=%p", opensles, args); - - flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; - + flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | + COMMAND_LINE_IGN_UNKNOWN_KEYWORD; status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, - rdpsnd_opensles_args, flags, opensles, NULL, NULL); + rdpsnd_opensles_args, flags, opensles, NULL, NULL); + if (status < 0) return status; @@ -389,14 +373,13 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device, continue; CommandLineSwitchStart(arg) - CommandLineSwitchCase(arg, "dev") { opensles->device_name = _strdup(arg->Value); + if (!opensles->device_name) return ERROR_OUTOFMEMORY; } - CommandLineSwitchEnd(arg) } while ((arg = CommandLineFindNextArgumentA(arg)) != NULL); @@ -418,15 +401,14 @@ static int rdpsnd_opensles_parse_addin_args(rdpsndDevicePlugin* device, * @return 0 on success, otherwise a Win32 error code */ UINT freerdp_rdpsnd_client_subsystem_entry( - PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) + PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { ADDIN_ARGV* args; rdpsndopenslesPlugin* opensles; UINT error; - DEBUG_SND("pEntryPoints=%p", pEntryPoints); - opensles = (rdpsndopenslesPlugin*) calloc(1, sizeof(rdpsndopenslesPlugin)); + if (!opensles) return CHANNEL_RC_NO_MEMORY; @@ -439,13 +421,13 @@ UINT freerdp_rdpsnd_client_subsystem_entry( opensles->device.Play = rdpsnd_opensles_play; opensles->device.Close = rdpsnd_opensles_close; opensles->device.Free = rdpsnd_opensles_free; - args = pEntryPoints->args; rdpsnd_opensles_parse_addin_args((rdpsndDevicePlugin*) opensles, args); if (!opensles->device_name) { opensles->device_name = _strdup("default"); + if (!opensles->device_name) { error = CHANNEL_RC_NO_MEMORY; @@ -456,8 +438,8 @@ UINT freerdp_rdpsnd_client_subsystem_entry( opensles->rate = 44100; opensles->channels = 2; opensles->format = WAVE_FORMAT_ADPCM; - opensles->dsp_context = freerdp_dsp_context_new(); + if (!opensles->dsp_context) { error = CHANNEL_RC_NO_MEMORY; @@ -465,8 +447,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry( } pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, - (rdpsndDevicePlugin*) opensles); - + (rdpsndDevicePlugin*) opensles); DEBUG_SND("success"); return CHANNEL_RC_OK; out_dsp_new: diff --git a/client/Android/android_cliprdr.h b/client/Android/android_cliprdr.h index bbc081e00..f7fdd6006 100644 --- a/client/Android/android_cliprdr.h +++ b/client/Android/android_cliprdr.h @@ -21,12 +21,16 @@ #define __ANDROID_CLIPRDR_H__ #include +#include #include "android_freerdp.h" -UINT android_cliprdr_send_client_format_list(CliprdrClientContext* cliprdr); +FREERDP_LOCAL UINT android_cliprdr_send_client_format_list( + CliprdrClientContext* cliprdr); -BOOL android_cliprdr_init(androidContext* afc, CliprdrClientContext* cliprdr); -BOOL android_cliprdr_uninit(androidContext* afc, CliprdrClientContext* cliprdr); +FREERDP_LOCAL BOOL android_cliprdr_init(androidContext* afc, + CliprdrClientContext* cliprdr); +FREERDP_LOCAL BOOL android_cliprdr_uninit(androidContext* afc, + CliprdrClientContext* cliprdr); #endif /* __ANDROID_CLIPRDR_H__ */ diff --git a/client/Android/android_event.c b/client/Android/android_event.c index 83fa5914c..19b246c34 100644 --- a/client/Android/android_event.c +++ b/client/Android/android_event.c @@ -233,7 +233,7 @@ static void android_event_cursor_free(ANDROID_EVENT_CURSOR* event) free(event); } -ANDROID_EVENT* android_event_disconnect_new() +ANDROID_EVENT* android_event_disconnect_new(void) { ANDROID_EVENT* event; event = (ANDROID_EVENT*) calloc(1, sizeof(ANDROID_EVENT)); diff --git a/client/Android/android_event.h b/client/Android/android_event.h index 60aab2eb3..38e00f372 100644 --- a/client/Android/android_event.h +++ b/client/Android/android_event.h @@ -12,6 +12,7 @@ #ifndef FREERDP_ANDROID_EVENT_H #define FREERDP_ANDROID_EVENT_H #include +#include #define EVENT_TYPE_KEY 1 #define EVENT_TYPE_CURSOR 2 @@ -55,24 +56,27 @@ struct _ANDROID_EVENT_QUEUE int size; int count; HANDLE isSet; - ANDROID_EVENT **events; + ANDROID_EVENT** events; }; typedef struct _ANDROID_EVENT_QUEUE ANDROID_EVENT_QUEUE; -BOOL android_push_event(freerdp * inst, ANDROID_EVENT* event); +FREERDP_LOCAL BOOL android_push_event(freerdp* inst, ANDROID_EVENT* event); -HANDLE android_get_handle(freerdp* inst); -BOOL android_check_handle(freerdp * inst); +FREERDP_LOCAL HANDLE android_get_handle(freerdp* inst); +FREERDP_LOCAL BOOL android_check_handle(freerdp* inst); -ANDROID_EVENT_KEY* android_event_key_new(int flags, UINT16 scancode); -ANDROID_EVENT_KEY* android_event_unicodekey_new(UINT16 key); -ANDROID_EVENT_CURSOR* android_event_cursor_new(UINT16 flags, UINT16 x, UINT16 y); -ANDROID_EVENT* android_event_disconnect_new(void); -ANDROID_EVENT_CLIPBOARD* android_event_clipboard_new(void* data, int data_length); +FREERDP_LOCAL ANDROID_EVENT_KEY* android_event_key_new(int flags, + UINT16 scancode); +FREERDP_LOCAL ANDROID_EVENT_KEY* android_event_unicodekey_new(UINT16 key); +FREERDP_LOCAL ANDROID_EVENT_CURSOR* android_event_cursor_new(UINT16 flags, + UINT16 x, UINT16 y); +FREERDP_LOCAL ANDROID_EVENT* android_event_disconnect_new(void); +FREERDP_LOCAL ANDROID_EVENT_CLIPBOARD* android_event_clipboard_new(void* data, + int data_length); -void android_event_free(ANDROID_EVENT* event); +FREERDP_LOCAL void android_event_free(ANDROID_EVENT* event); -BOOL android_event_queue_init(freerdp * inst); -void android_event_queue_uninit(freerdp * inst); +FREERDP_LOCAL BOOL android_event_queue_init(freerdp* inst); +FREERDP_LOCAL void android_event_queue_uninit(freerdp* inst); #endif /* FREERDP_ANDROID_EVENT_H */ diff --git a/client/Android/android_jni_callback.c b/client/Android/android_jni_callback.c index 64985d600..d8a5dcf3e 100644 --- a/client/Android/android_jni_callback.c +++ b/client/Android/android_jni_callback.c @@ -23,16 +23,14 @@ static JavaVM* jVM; static jobject jLibFreeRDPObject; -static const char *jLibFreeRDPPath = JAVA_LIBFREERDP_CLASS; +static const char* jLibFreeRDPPath = JAVA_LIBFREERDP_CLASS; -void jni_load_class(JNIEnv *env, const char *path, jobject *objptr) +static void jni_load_class(JNIEnv* env, const char* path, jobject* objptr) { jclass class; jmethodID method; jobject object; - WLog_DBG(TAG, "jni_load_class: %s", path); - class = (*env)->FindClass(env, path); if (!class) @@ -58,17 +56,15 @@ void jni_load_class(JNIEnv *env, const char *path, jobject *objptr) } (*objptr) = (*env)->NewGlobalRef(env, object); - finish: - while(0); + + while (0); } jint init_callback_environment(JavaVM* vm, JNIEnv* env) { jVM = vm; - jni_load_class(env, jLibFreeRDPPath, &jLibFreeRDPObject); - return JNI_VERSION_1_6; } @@ -78,12 +74,12 @@ jboolean jni_attach_thread(JNIEnv** env) if ((*jVM)->GetEnv(jVM, (void**) env, JNI_VERSION_1_4) != JNI_OK) { WLog_DBG(TAG, "android_java_callback: attaching current thread"); - (*jVM)->AttachCurrentThread(jVM, env, NULL); if ((*jVM)->GetEnv(jVM, (void**) env, JNI_VERSION_1_4) != JNI_OK) { - WLog_ERR(TAG, "android_java_callback: failed to obtain current JNI environment"); + WLog_ERR(TAG, + "android_java_callback: failed to obtain current JNI environment"); } return JNI_TRUE; @@ -99,17 +95,15 @@ void jni_detach_thread() } /* callback with void result */ -void java_callback_void(jobject obj, const char * callback, const char* signature, va_list args) +static void java_callback_void(jobject obj, const char* callback, + const char* signature, va_list args) { jclass jObjClass; jmethodID jCallback; jboolean attached; - JNIEnv *env; - + JNIEnv* env; WLog_DBG(TAG, "java_callback: %s (%s)", callback, signature); - attached = jni_attach_thread(&env); - jObjClass = (*env)->GetObjectClass(env, obj); if (!jObjClass) @@ -127,26 +121,23 @@ void java_callback_void(jobject obj, const char * callback, const char* signatur } (*env)->CallStaticVoidMethodV(env, jObjClass, jCallback, args); - finish: - if(attached == JNI_TRUE) + + if (attached == JNI_TRUE) jni_detach_thread(); } /* callback with bool result */ -jboolean java_callback_bool(jobject obj, const char * callback, - const char* signature, va_list args) +static jboolean java_callback_bool(jobject obj, const char* callback, + const char* signature, va_list args) { jclass jObjClass; jmethodID jCallback; jboolean attached; jboolean res = JNI_FALSE; - JNIEnv *env; - + JNIEnv* env; WLog_DBG(TAG, "java_callback: %s (%s)", callback, signature); - attached = jni_attach_thread(&env); - jObjClass = (*env)->GetObjectClass(env, obj); if (!jObjClass) @@ -164,27 +155,25 @@ jboolean java_callback_bool(jobject obj, const char * callback, } res = (*env)->CallStaticBooleanMethodV(env, jObjClass, jCallback, args); - finish: - if(attached == JNI_TRUE) + + if (attached == JNI_TRUE) jni_detach_thread(); return res; } /* callback with int result */ -jint java_callback_int(jobject obj, const char * callback, const char* signature, va_list args) +static jint java_callback_int(jobject obj, const char* callback, + const char* signature, va_list args) { jclass jObjClass; jmethodID jCallback; jboolean attached; jint res = -1; - JNIEnv *env; - + JNIEnv* env; WLog_DBG(TAG, "java_callback: %s (%s)", callback, signature); - attached = jni_attach_thread(&env); - jObjClass = (*env)->GetObjectClass(env, obj); if (!jObjClass) @@ -202,9 +191,9 @@ jint java_callback_int(jobject obj, const char * callback, const char* signature } res = (*env)->CallStaticIntMethodV(env, jObjClass, jCallback, args); - finish: - if(attached == JNI_TRUE) + + if (attached == JNI_TRUE) jni_detach_thread(); return res; @@ -212,7 +201,7 @@ finish: /* callback to freerdp class */ -void freerdp_callback(const char * callback, const char * signature, ...) +void freerdp_callback(const char* callback, const char* signature, ...) { va_list vl; va_start(vl, signature); @@ -220,7 +209,8 @@ void freerdp_callback(const char * callback, const char * signature, ...) va_end(vl); } -jboolean freerdp_callback_bool_result(const char * callback, const char * signature, ...) +jboolean freerdp_callback_bool_result(const char* callback, + const char* signature, ...) { va_list vl; va_start(vl, signature); @@ -229,10 +219,11 @@ jboolean freerdp_callback_bool_result(const char * callback, const char * signat return res; } -jint freerdp_callback_int_result(const char * callback, const char * signature, ...) +jint freerdp_callback_int_result(const char* callback, const char* signature, + ...) { va_list vl; - va_start(vl, signature); + va_start(vl, signature); jint res = java_callback_int(jLibFreeRDPObject, callback, signature, vl); va_end(vl); return res; diff --git a/client/Android/android_jni_callback.h b/client/Android/android_jni_callback.h index 95d0336ee..98af6f78b 100644 --- a/client/Android/android_jni_callback.h +++ b/client/Android/android_jni_callback.h @@ -15,13 +15,17 @@ #include #include +#include -jint init_callback_environment(JavaVM* vm, JNIEnv* env); -jboolean jni_attach_thread(JNIEnv** env); -void jni_detach_thread(void); -void freerdp_callback(const char * callback, const char * signature, ...); -jboolean freerdp_callback_bool_result(const char * callback, const char * signature, ...); -jint freerdp_callback_int_result(const char * callback, const char * signature, ...); +FREERDP_LOCAL jint init_callback_environment(JavaVM* vm, JNIEnv* env); +FREERDP_LOCAL jboolean jni_attach_thread(JNIEnv** env); +FREERDP_LOCAL void jni_detach_thread(void); +FREERDP_LOCAL void freerdp_callback(const char* callback, const char* signature, + ...); +FREERDP_LOCAL jboolean freerdp_callback_bool_result(const char* callback, + const char* signature, ...); +FREERDP_LOCAL jint freerdp_callback_int_result(const char* callback, + const char* signature, ...); #endif /* FREERDP_ANDROID_JNI_CALLBACK_H */ diff --git a/client/Android/android_jni_utils.h b/client/Android/android_jni_utils.h index 67be626d1..12816aeda 100644 --- a/client/Android/android_jni_utils.h +++ b/client/Android/android_jni_utils.h @@ -13,20 +13,22 @@ #define _ANDROID_JNI_UTILS_H_ #include +#include #ifdef __cplusplus extern "C" { #endif -JNIEnv* getJNIEnv(); -JavaVM* getJavaVM(); +FREERDP_LOCAL JNIEnv* getJNIEnv(); +FREERDP_LOCAL JavaVM* getJavaVM(); -char* get_string_from_string_builder(JNIEnv* env, jobject strBuilder); -jobject create_string_builder(JNIEnv *env, char* initialStr); -jstring jniNewStringUTF(JNIEnv* env, const char* in, int len); +FREERDP_LOCAL char* get_string_from_string_builder(JNIEnv* env, + jobject strBuilder); +FREERDP_LOCAL jobject create_string_builder(JNIEnv* env, char* initialStr); +FREERDP_LOCAL jstring jniNewStringUTF(JNIEnv* env, const char* in, int len); -extern JavaVM *g_JavaVm; +FREERDP_LOCAL extern JavaVM* g_JavaVm; #ifdef __cplusplus }