mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-24 01:04:02 +02:00
Add support for the f32 format for OpenSL|ES.
This commit is contained in:
@@ -1518,7 +1518,16 @@ static void mal_samples_to_f32(float* pSamplesOut, const void* pSamplesIn, mal_u
|
|||||||
mal_int16* pSamplesInS16 = (mal_int16*)pSamplesIn;
|
mal_int16* pSamplesInS16 = (mal_int16*)pSamplesIn;
|
||||||
for (mal_uint32 i = 0; i < sampleCount; ++i) {
|
for (mal_uint32 i = 0; i < sampleCount; ++i) {
|
||||||
mal_uint32 sign = (pSamplesInS16[i] & 0x8000) >> 15;
|
mal_uint32 sign = (pSamplesInS16[i] & 0x8000) >> 15;
|
||||||
pSamplesOut[i] = (pSamplesInS16[i] / (float)(32767 + sign));
|
pSamplesOut[i] = (pSamplesInS16[i] / (float)(0x7FFF + sign));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mal_format_s32:
|
||||||
|
{
|
||||||
|
mal_int32* pSamplesInS32 = (mal_int32*)pSamplesIn;
|
||||||
|
for (mal_uint32 i = 0; i < sampleCount; ++i) {
|
||||||
|
mal_uint32 sign = (pSamplesInS32[i] & 0x80000000) >> 31;
|
||||||
|
pSamplesOut[i] = (pSamplesInS32[i] / (float)(0x7FFFFFFF + sign));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -1570,9 +1579,19 @@ static void mal_samples_from_f32(void* pSamplesOut, const float* pSamplesIn, mal
|
|||||||
float sampleIn = mal_clip_f32(pSamplesIn[i]);
|
float sampleIn = mal_clip_f32(pSamplesIn[i]);
|
||||||
|
|
||||||
mal_uint32 sign = ((*((mal_uint32*)&pSamplesIn[i])) & 0x80000000) >> 31;
|
mal_uint32 sign = ((*((mal_uint32*)&pSamplesIn[i])) & 0x80000000) >> 31;
|
||||||
pSamplesOutS16[i] = (mal_int16)(sampleIn * (32767 + sign));
|
pSamplesOutS16[i] = (mal_int16)(sampleIn * (0x7FFF + sign));
|
||||||
}
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case mal_format_s32:
|
||||||
|
{
|
||||||
|
mal_int32* pSamplesOutS32 = (mal_int32*)pSamplesOut;
|
||||||
|
for (mal_uint32 i = 0; i < sampleCount; ++i) {
|
||||||
|
float sampleIn = mal_clip_f32(pSamplesIn[i]);
|
||||||
|
|
||||||
|
mal_uint32 sign = ((*((mal_uint32*)&pSamplesIn[i])) & 0x80000000) >> 31;
|
||||||
|
pSamplesOutS32[i] = (mal_int32)(sampleIn * (0x7FFFFFFF + sign));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
@@ -3900,7 +3919,7 @@ static void mal_buffer_queue_callback__opensl_android(SLAndroidSimpleBufferQueue
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t periodSizeInBytes = pDevice->opensl.periodSizeInFrames * pDevice->channels * mal_get_sample_size_in_bytes(pDevice->format);
|
size_t periodSizeInBytes = pDevice->opensl.periodSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat);
|
||||||
mal_uint8* pBuffer = pDevice->opensl.pBuffer + (pDevice->opensl.currentBufferIndex * periodSizeInBytes);
|
mal_uint8* pBuffer = pDevice->opensl.pBuffer + (pDevice->opensl.currentBufferIndex * periodSizeInBytes);
|
||||||
|
|
||||||
if (pDevice->type == mal_device_type_playback) {
|
if (pDevice->type == mal_device_type_playback) {
|
||||||
@@ -3961,10 +3980,9 @@ static mal_result mal_device_init__opensl(mal_context* pContext, mal_device_type
|
|||||||
return MAL_NO_BACKEND;
|
return MAL_NO_BACKEND;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Currently only supporting simple PCM formats. 32-bit floating point is not currently supported,
|
// Use s32 as the internal format for when floating point is specified.
|
||||||
// but may be emulated later on.
|
|
||||||
if (pConfig->format == mal_format_f32) {
|
if (pConfig->format == mal_format_f32) {
|
||||||
return MAL_FORMAT_NOT_SUPPORTED;
|
pDevice->internalFormat = mal_format_s32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize global data first if applicable.
|
// Initialize global data first if applicable.
|
||||||
@@ -4000,11 +4018,11 @@ static mal_result mal_device_init__opensl(mal_context* pContext, mal_device_type
|
|||||||
|
|
||||||
SLDataFormat_PCM pcm;
|
SLDataFormat_PCM pcm;
|
||||||
pcm.formatType = SL_DATAFORMAT_PCM;
|
pcm.formatType = SL_DATAFORMAT_PCM;
|
||||||
pcm.numChannels = pConfig->channels;
|
pcm.numChannels = pDevice->internalChannels;
|
||||||
pcm.samplesPerSec = pConfig->sampleRate * 1000; // In millihertz because, you know, the people who wrote the OpenSL|ES spec thought it would be funny to be the _only_ API to do this...
|
pcm.samplesPerSec = pDevice->internalSampleRate * 1000; // In millihertz because, you know, the people who wrote the OpenSL|ES spec thought it would be funny to be the _only_ API to do this...
|
||||||
pcm.bitsPerSample = mal_get_sample_size_in_bytes(pConfig->format) * 8;
|
pcm.bitsPerSample = mal_get_sample_size_in_bytes(pDevice->internalFormat)*8;
|
||||||
pcm.containerSize = pcm.bitsPerSample; // Always tightly packed for now.
|
pcm.containerSize = pcm.bitsPerSample; // Always tightly packed for now.
|
||||||
pcm.channelMask = ~((~0UL) << pConfig->channels);
|
pcm.channelMask = ~((~0UL) << pDevice->internalChannels);
|
||||||
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
||||||
|
|
||||||
if (type == mal_device_type_playback) {
|
if (type == mal_device_type_playback) {
|
||||||
@@ -4109,7 +4127,7 @@ static mal_result mal_device_init__opensl(mal_context* pContext, mal_device_type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bufferSizeInBytes = pDevice->bufferSizeInFrames * pDevice->channels * mal_get_sample_size_in_bytes(pDevice->format);
|
size_t bufferSizeInBytes = pDevice->bufferSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat);
|
||||||
pDevice->opensl.pBuffer = (mal_uint8*)mal_malloc(bufferSizeInBytes);
|
pDevice->opensl.pBuffer = (mal_uint8*)mal_malloc(bufferSizeInBytes);
|
||||||
if (pDevice->opensl.pBuffer == NULL) {
|
if (pDevice->opensl.pBuffer == NULL) {
|
||||||
mal_device_uninit__opensl(pDevice);
|
mal_device_uninit__opensl(pDevice);
|
||||||
@@ -4134,7 +4152,7 @@ static mal_result mal_device__start_backend__opensl(mal_device* pDevice)
|
|||||||
// We need to enqueue a buffer for each period.
|
// We need to enqueue a buffer for each period.
|
||||||
mal_device__read_frames_from_client(pDevice, pDevice->bufferSizeInFrames, pDevice->opensl.pBuffer);
|
mal_device__read_frames_from_client(pDevice, pDevice->bufferSizeInFrames, pDevice->opensl.pBuffer);
|
||||||
|
|
||||||
size_t periodSizeInBytes = pDevice->opensl.periodSizeInFrames * pDevice->channels * mal_get_sample_size_in_bytes(pDevice->format);
|
size_t periodSizeInBytes = pDevice->opensl.periodSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat);
|
||||||
for (mal_uint32 iPeriod = 0; iPeriod < pDevice->periods; ++iPeriod) {
|
for (mal_uint32 iPeriod = 0; iPeriod < pDevice->periods; ++iPeriod) {
|
||||||
resultSL = MAL_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueue)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueue, pDevice->opensl.pBuffer + (periodSizeInBytes * iPeriod), periodSizeInBytes);
|
resultSL = MAL_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueue)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueue, pDevice->opensl.pBuffer + (periodSizeInBytes * iPeriod), periodSizeInBytes);
|
||||||
if (resultSL != SL_RESULT_SUCCESS) {
|
if (resultSL != SL_RESULT_SUCCESS) {
|
||||||
@@ -4148,7 +4166,7 @@ static mal_result mal_device__start_backend__opensl(mal_device* pDevice)
|
|||||||
return MAL_FAILED_TO_START_BACKEND_DEVICE;
|
return MAL_FAILED_TO_START_BACKEND_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t periodSizeInBytes = pDevice->opensl.periodSizeInFrames * pDevice->channels * mal_get_sample_size_in_bytes(pDevice->format);
|
size_t periodSizeInBytes = pDevice->opensl.periodSizeInFrames * pDevice->internalChannels * mal_get_sample_size_in_bytes(pDevice->internalFormat);
|
||||||
for (mal_uint32 iPeriod = 0; iPeriod < pDevice->periods; ++iPeriod) {
|
for (mal_uint32 iPeriod = 0; iPeriod < pDevice->periods; ++iPeriod) {
|
||||||
resultSL = MAL_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueue)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueue, pDevice->opensl.pBuffer + (periodSizeInBytes * iPeriod), periodSizeInBytes);
|
resultSL = MAL_OPENSL_BUFFERQUEUE(pDevice->opensl.pBufferQueue)->Enqueue((SLAndroidSimpleBufferQueueItf)pDevice->opensl.pBufferQueue, pDevice->opensl.pBuffer + (periodSizeInBytes * iPeriod), periodSizeInBytes);
|
||||||
if (resultSL != SL_RESULT_SUCCESS) {
|
if (resultSL != SL_RESULT_SUCCESS) {
|
||||||
@@ -5563,6 +5581,7 @@ mal_uint32 mal_get_sample_size_in_bytes(mal_format format)
|
|||||||
// to test and maintain, and just generally unreliable.
|
// to test and maintain, and just generally unreliable.
|
||||||
// - Null Backend: Fixed a crash when recording.
|
// - Null Backend: Fixed a crash when recording.
|
||||||
// - Fixed build for UWP.
|
// - Fixed build for UWP.
|
||||||
|
// - Added support for f32 formats to the OpenSL|ES backend.
|
||||||
// - Added initial implementation of the WASAPI backend.
|
// - Added initial implementation of the WASAPI backend.
|
||||||
// - Added initial implementation of the OpenAL backend.
|
// - Added initial implementation of the OpenAL backend.
|
||||||
//
|
//
|
||||||
@@ -5609,8 +5628,6 @@ mal_uint32 mal_get_sample_size_in_bytes(mal_format format)
|
|||||||
// OpenSL|ES / Android
|
// OpenSL|ES / Android
|
||||||
// -------------------
|
// -------------------
|
||||||
// - Test!
|
// - Test!
|
||||||
// - Add software f32 conversion
|
|
||||||
// - 32-bit floating point is only supported from Android API Level 21.
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user