mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-23 08:44:04 +02:00
OSS: Optimize memory allocations during device initialization.
This commit is contained in:
+59
-40
@@ -38978,8 +38978,7 @@ typedef struct ma_device_state_oss
|
|||||||
{
|
{
|
||||||
int fdPlayback;
|
int fdPlayback;
|
||||||
int fdCapture;
|
int fdCapture;
|
||||||
void* pIntermediaryBufferPlayback;
|
void* pIntermediaryBuffer;
|
||||||
void* pIntermediaryBufferCapture;
|
|
||||||
} ma_device_state_oss;
|
} ma_device_state_oss;
|
||||||
|
|
||||||
static ma_context_state_oss* ma_context_get_backend_state__oss(ma_context* pContext)
|
static ma_context_state_oss* ma_context_get_backend_state__oss(ma_context* pContext)
|
||||||
@@ -39512,7 +39511,7 @@ static ma_result ma_context_enumerate_devices__oss(ma_context* pContext, ma_enum
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_config_oss* pDeviceConfigOSS, ma_device_descriptor* pDescriptor, ma_device_type deviceType, int* pFD, void** ppIntermediaryBuffer)
|
static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_config_oss* pDeviceConfigOSS, ma_device_descriptor* pDescriptor, ma_device_type deviceType, int* pFD)
|
||||||
{
|
{
|
||||||
ma_result result;
|
ma_result result;
|
||||||
int ossResult;
|
int ossResult;
|
||||||
@@ -39523,12 +39522,10 @@ static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_conf
|
|||||||
int ossChannels;
|
int ossChannels;
|
||||||
int ossSampleRate;
|
int ossSampleRate;
|
||||||
int ossFragment;
|
int ossFragment;
|
||||||
void* pIntermediaryBuffer;
|
|
||||||
|
|
||||||
MA_ASSERT(pDevice != NULL);
|
MA_ASSERT(pDevice != NULL);
|
||||||
MA_ASSERT(pDeviceConfigOSS != NULL);
|
MA_ASSERT(pDeviceConfigOSS != NULL);
|
||||||
MA_ASSERT(pFD != NULL);
|
MA_ASSERT(pFD != NULL);
|
||||||
MA_ASSERT(ppIntermediaryBuffer != NULL);
|
|
||||||
MA_ASSERT(deviceType != ma_device_type_duplex);
|
MA_ASSERT(deviceType != ma_device_type_duplex);
|
||||||
|
|
||||||
pDeviceID = pDescriptor->pDeviceID;
|
pDeviceID = pDescriptor->pDeviceID;
|
||||||
@@ -39623,25 +39620,35 @@ static ma_result ma_device_init_fd__oss(ma_device* pDevice, const ma_device_conf
|
|||||||
return MA_FORMAT_NOT_SUPPORTED;
|
return MA_FORMAT_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
pIntermediaryBuffer = ma_malloc(ma_get_bytes_per_frame(pDescriptor->format, pDescriptor->channels) * pDescriptor->periodSizeInFrames, ma_device_get_allocation_callbacks(pDevice));
|
|
||||||
if (pIntermediaryBuffer == NULL) {
|
|
||||||
close(fd);
|
|
||||||
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to allocate memory for intermediary buffer.");
|
|
||||||
return MA_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pFD = fd;
|
*pFD = fd;
|
||||||
*ppIntermediaryBuffer = pIntermediaryBuffer;
|
|
||||||
|
|
||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ma_device_uninit_internal__oss(ma_device* pDevice, ma_device_state_oss* pDeviceStateOSS)
|
||||||
|
{
|
||||||
|
ma_device_type deviceType = ma_device_get_type(pDevice);
|
||||||
|
|
||||||
|
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) {
|
||||||
|
close(pDeviceStateOSS->fdCapture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
|
||||||
|
close(pDeviceStateOSS->fdPlayback);
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
|
||||||
|
}
|
||||||
|
|
||||||
static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBackendConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture, void** ppDeviceState)
|
static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBackendConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture, void** ppDeviceState)
|
||||||
{
|
{
|
||||||
ma_device_state_oss* pDeviceStateOSS;
|
ma_device_state_oss* pDeviceStateOSS;
|
||||||
const ma_device_config_oss* pDeviceConfigOSS = (const ma_device_config_oss*)pDeviceBackendConfig;
|
const ma_device_config_oss* pDeviceConfigOSS = (const ma_device_config_oss*)pDeviceBackendConfig;
|
||||||
ma_device_config_oss defaultConfigOSS;
|
ma_device_config_oss defaultConfigOSS;
|
||||||
ma_device_type deviceType = ma_device_get_type(pDevice);
|
ma_device_type deviceType = ma_device_get_type(pDevice);
|
||||||
|
ma_uint32 intermediaryBufferSizeCapture = 0;
|
||||||
|
ma_uint32 intermediaryBufferSizePlayback = 0;
|
||||||
|
ma_uint32 intermediaryBufferAllocationSize = 0;
|
||||||
|
|
||||||
if (pDeviceConfigOSS == NULL) {
|
if (pDeviceConfigOSS == NULL) {
|
||||||
defaultConfigOSS = ma_device_config_oss_init();
|
defaultConfigOSS = ma_device_config_oss_init();
|
||||||
@@ -39658,28 +39665,53 @@ static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBack
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) {
|
if (deviceType == ma_device_type_capture || deviceType == ma_device_type_duplex) {
|
||||||
ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorCapture, ma_device_type_capture, &pDeviceStateOSS->fdCapture, &pDeviceStateOSS->pIntermediaryBufferCapture);
|
ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorCapture, ma_device_type_capture, &pDeviceStateOSS->fdCapture);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
|
|
||||||
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device.");
|
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device.");
|
||||||
|
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intermediaryBufferSizeCapture = ma_get_bytes_per_frame(pDescriptorCapture->format, pDescriptorCapture->channels) * pDescriptorCapture->periodSizeInFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
|
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
|
||||||
ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorPlayback, ma_device_type_playback, &pDeviceStateOSS->fdPlayback, &pDeviceStateOSS->pIntermediaryBufferPlayback);
|
ma_result result = ma_device_init_fd__oss(pDevice, pDeviceConfigOSS, pDescriptorPlayback, ma_device_type_playback, &pDeviceStateOSS->fdPlayback);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
if (deviceType == ma_device_type_duplex) {
|
|
||||||
close(pDeviceStateOSS->fdCapture);
|
|
||||||
ma_free(pDeviceStateOSS->pIntermediaryBufferCapture, ma_device_get_allocation_callbacks(pDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
|
|
||||||
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device.");
|
ma_log_post(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[OSS] Failed to open device.");
|
||||||
|
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intermediaryBufferSizePlayback = ma_get_bytes_per_frame(pDescriptorPlayback->format, pDescriptorPlayback->channels) * pDescriptorPlayback->periodSizeInFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We need an intermediary buffer. Since the capture and playback sides are never used simultaneously we can make
|
||||||
|
this the size of the maximum of the two. We can attach this to the end of the device state allocation.
|
||||||
|
*/
|
||||||
|
intermediaryBufferAllocationSize = ma_align_64(ma_max(intermediaryBufferSizeCapture, intermediaryBufferSizePlayback));
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t deviceStateAllocationSizeNew;
|
||||||
|
ma_device_state_oss* pDeviceStateOSSNew;
|
||||||
|
|
||||||
|
deviceStateAllocationSizeNew = 0;
|
||||||
|
deviceStateAllocationSizeNew += ma_align_64(sizeof(*pDeviceStateOSS));
|
||||||
|
deviceStateAllocationSizeNew += ma_align_64(intermediaryBufferAllocationSize);
|
||||||
|
|
||||||
|
pDeviceStateOSSNew = (ma_device_state_oss*)ma_realloc(pDeviceStateOSS, deviceStateAllocationSizeNew, ma_device_get_allocation_callbacks(pDevice));
|
||||||
|
if (pDeviceStateOSSNew == NULL) {
|
||||||
|
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
|
||||||
|
return MA_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDeviceStateOSS = pDeviceStateOSSNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDeviceStateOSS->pIntermediaryBuffer = ma_offset_ptr(pDeviceStateOSS, ma_align_64(sizeof(*pDeviceStateOSS)));
|
||||||
|
|
||||||
|
|
||||||
*ppDeviceState = pDeviceStateOSS;
|
*ppDeviceState = pDeviceStateOSS;
|
||||||
|
|
||||||
return MA_SUCCESS;
|
return MA_SUCCESS;
|
||||||
@@ -39688,20 +39720,7 @@ static ma_result ma_device_init__oss(ma_device* pDevice, const void* pDeviceBack
|
|||||||
static void ma_device_uninit__oss(ma_device* pDevice)
|
static void ma_device_uninit__oss(ma_device* pDevice)
|
||||||
{
|
{
|
||||||
ma_device_state_oss* pDeviceStateOSS = ma_device_get_backend_state__oss(pDevice);
|
ma_device_state_oss* pDeviceStateOSS = ma_device_get_backend_state__oss(pDevice);
|
||||||
|
ma_device_uninit_internal__oss(pDevice, pDeviceStateOSS);
|
||||||
MA_ASSERT(pDevice != NULL);
|
|
||||||
|
|
||||||
if (pDevice->type == ma_device_type_capture || pDevice->type == ma_device_type_duplex) {
|
|
||||||
close(pDeviceStateOSS->fdCapture);
|
|
||||||
ma_free(pDeviceStateOSS->pIntermediaryBufferCapture, ma_device_get_allocation_callbacks(pDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
|
|
||||||
close(pDeviceStateOSS->fdPlayback);
|
|
||||||
ma_free(pDeviceStateOSS->pIntermediaryBufferPlayback, ma_device_get_allocation_callbacks(pDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
ma_free(pDeviceStateOSS, ma_device_get_allocation_callbacks(pDevice));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -39873,20 +39892,20 @@ static ma_result ma_device_step__oss(ma_device* pDevice, ma_blocking_mode blocki
|
|||||||
if (FD_ISSET(pDeviceStateOSS->fdCapture, &fdsRead)) {
|
if (FD_ISSET(pDeviceStateOSS->fdCapture, &fdsRead)) {
|
||||||
ma_uint32 framesRead;
|
ma_uint32 framesRead;
|
||||||
|
|
||||||
result = ma_device_read__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferCapture, pDevice->capture.internalPeriodSizeInFrames, &framesRead);
|
result = ma_device_read__oss(pDevice, pDeviceStateOSS->pIntermediaryBuffer, pDevice->capture.internalPeriodSizeInFrames, &framesRead);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_device_handle_backend_data_callback(pDevice, NULL, pDeviceStateOSS->pIntermediaryBufferCapture, framesRead);
|
ma_device_handle_backend_data_callback(pDevice, NULL, pDeviceStateOSS->pIntermediaryBuffer, framesRead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
|
if (deviceType == ma_device_type_playback || deviceType == ma_device_type_duplex) {
|
||||||
if (FD_ISSET(pDeviceStateOSS->fdPlayback, &fdsWrite)) {
|
if (FD_ISSET(pDeviceStateOSS->fdPlayback, &fdsWrite)) {
|
||||||
ma_device_handle_backend_data_callback(pDevice, pDeviceStateOSS->pIntermediaryBufferPlayback, NULL, pDevice->playback.internalPeriodSizeInFrames);
|
ma_device_handle_backend_data_callback(pDevice, pDeviceStateOSS->pIntermediaryBuffer, NULL, pDevice->playback.internalPeriodSizeInFrames);
|
||||||
|
|
||||||
result = ma_device_write__oss(pDevice, pDeviceStateOSS->pIntermediaryBufferPlayback, pDevice->playback.internalPeriodSizeInFrames, NULL);
|
result = ma_device_write__oss(pDevice, pDeviceStateOSS->pIntermediaryBuffer, pDevice->playback.internalPeriodSizeInFrames, NULL);
|
||||||
if (result != MA_SUCCESS) {
|
if (result != MA_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user