audio: malloc reductions
Just malloc all of the audioOutput array in one shot to avoid fragmentation and to improve cache locality when iterating through the array. We also know name and type members of the AudioOutput struct won't change in the config, so there's no need to strdup them. newAudioOutput => initAudioOutput git-svn-id: https://svn.musicpd.org/mpd/trunk@4515 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
b0965c317b
commit
eb537f84f1
53
src/audio.c
53
src/audio.c
@ -44,7 +44,7 @@ static AudioFormat audio_format;
|
|||||||
|
|
||||||
static AudioFormat *audio_configFormat = NULL;
|
static AudioFormat *audio_configFormat = NULL;
|
||||||
|
|
||||||
static AudioOutput **audioOutputArray = NULL;
|
static AudioOutput *audioOutputArray = NULL;
|
||||||
static mpd_uint8 audioOutputArraySize = 0;
|
static mpd_uint8 audioOutputArraySize = 0;
|
||||||
|
|
||||||
#define DEVICE_OFF 0x00
|
#define DEVICE_OFF 0x00
|
||||||
@ -120,33 +120,30 @@ void initAudioDriver(void)
|
|||||||
|
|
||||||
audioOutputArraySize = audio_device_count();
|
audioOutputArraySize = audio_device_count();
|
||||||
audioDeviceStates = (getPlayerData())->audioDeviceStates;
|
audioDeviceStates = (getPlayerData())->audioDeviceStates;
|
||||||
audioOutputArray = malloc(sizeof(AudioOutput *) * audioOutputArraySize);
|
audioOutputArray = malloc(sizeof(AudioOutput) * audioOutputArraySize);
|
||||||
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
param = getNextConfigParam(CONF_AUDIO_OUTPUT, param);
|
param = getNextConfigParam(CONF_AUDIO_OUTPUT, param);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
AudioOutput *output;
|
AudioOutput *output = &audioOutputArray[i];
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
output = newAudioOutput(param);
|
if (!initAudioOutput(output, param) && param) {
|
||||||
if (!output && param) {
|
|
||||||
ERROR("problems configuring output device defined at "
|
ERROR("problems configuring output device defined at "
|
||||||
"line %i\n", param->line);
|
"line %i\n", param->line);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* require output names to be unique: */
|
/* require output names to be unique: */
|
||||||
for (j = i - 1; j >= 0; --j) {
|
for (j = i; --j >= 0; ) {
|
||||||
if (!strcmp(output->name, audioOutputArray[j]->name)) {
|
if (!strcmp(output->name, audioOutputArray[j].name)) {
|
||||||
ERROR("output devices with identical "
|
ERROR("output devices with identical "
|
||||||
"names: %s\n", output->name);
|
"names: %s\n", output->name);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
audioDeviceStates[i] = DEVICE_ENABLE;
|
audioDeviceStates[i++] = DEVICE_ENABLE;
|
||||||
audioOutputArray[i++] = output;
|
|
||||||
} while ((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)));
|
} while ((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +250,7 @@ void finishAudioDriver(void)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < audioOutputArraySize; i++) {
|
for (i = 0; i < audioOutputArraySize; i++) {
|
||||||
finishAudioOutput(audioOutputArray[i]);
|
finishAudioOutput(&audioOutputArray[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(audioOutputArray);
|
free(audioOutputArray);
|
||||||
@ -283,11 +280,11 @@ static int flushAudioBuffer(void)
|
|||||||
for (i = audioOutputArraySize; --i >= 0; ) {
|
for (i = audioOutputArraySize; --i >= 0; ) {
|
||||||
switch (audioDeviceStates[i]) {
|
switch (audioDeviceStates[i]) {
|
||||||
case DEVICE_ENABLE:
|
case DEVICE_ENABLE:
|
||||||
openAudioOutput(audioOutputArray[i], &audio_format);
|
openAudioOutput(&audioOutputArray[i], &audio_format);
|
||||||
audioDeviceStates[i] = DEVICE_ON;
|
audioDeviceStates[i] = DEVICE_ON;
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case DEVICE_ON:
|
case DEVICE_ON:
|
||||||
err = playAudioOutput(audioOutputArray[i], audioBuffer,
|
err = playAudioOutput(&audioOutputArray[i], audioBuffer,
|
||||||
audioBufferPos);
|
audioBufferPos);
|
||||||
if (!err)
|
if (!err)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -297,8 +294,8 @@ static int flushAudioBuffer(void)
|
|||||||
audioDeviceStates[i] = DEVICE_OFF;
|
audioDeviceStates[i] = DEVICE_OFF;
|
||||||
break;
|
break;
|
||||||
case DEVICE_DISABLE:
|
case DEVICE_DISABLE:
|
||||||
dropBufferedAudioOutput(audioOutputArray[i]);
|
dropBufferedAudioOutput(&audioOutputArray[i]);
|
||||||
closeAudioOutput(audioOutputArray[i]);
|
closeAudioOutput(&audioOutputArray[i]);
|
||||||
audioDeviceStates[i] = DEVICE_OFF;
|
audioDeviceStates[i] = DEVICE_OFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -330,15 +327,15 @@ int openAudioDevice(AudioFormat * audioFormat)
|
|||||||
for (i = audioOutputArraySize; --i >= 0; ) {
|
for (i = audioOutputArraySize; --i >= 0; ) {
|
||||||
switch (audioDeviceStates[i]) {
|
switch (audioDeviceStates[i]) {
|
||||||
case DEVICE_ENABLE:
|
case DEVICE_ENABLE:
|
||||||
openAudioOutput(audioOutputArray[i], &audio_format);
|
openAudioOutput(&audioOutputArray[i], &audio_format);
|
||||||
audioDeviceStates[i] = DEVICE_ON;
|
audioDeviceStates[i] = DEVICE_ON;
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case DEVICE_ON:
|
case DEVICE_ON:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case DEVICE_DISABLE:
|
case DEVICE_DISABLE:
|
||||||
dropBufferedAudioOutput(audioOutputArray[i]);
|
dropBufferedAudioOutput(&audioOutputArray[i]);
|
||||||
closeAudioOutput(audioOutputArray[i]);
|
closeAudioOutput(&audioOutputArray[i]);
|
||||||
audioDeviceStates[i] = DEVICE_OFF;
|
audioDeviceStates[i] = DEVICE_OFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -349,7 +346,7 @@ int openAudioDevice(AudioFormat * audioFormat)
|
|||||||
else {
|
else {
|
||||||
/* close all devices if there was an error */
|
/* close all devices if there was an error */
|
||||||
for (i = audioOutputArraySize; --i >= 0; ) {
|
for (i = audioOutputArraySize; --i >= 0; ) {
|
||||||
closeAudioOutput(audioOutputArray[i]);
|
closeAudioOutput(&audioOutputArray[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
audioOpened = 0;
|
audioOpened = 0;
|
||||||
@ -393,17 +390,17 @@ void dropBufferedAudio(void)
|
|||||||
for (i = audioOutputArraySize; --i >= 0; ) {
|
for (i = audioOutputArraySize; --i >= 0; ) {
|
||||||
switch (audioDeviceStates[i]) {
|
switch (audioDeviceStates[i]) {
|
||||||
case DEVICE_ON:
|
case DEVICE_ON:
|
||||||
dropBufferedAudioOutput(audioOutputArray[i]);
|
dropBufferedAudioOutput(&audioOutputArray[i]);
|
||||||
break;
|
break;
|
||||||
case DEVICE_ENABLE:
|
case DEVICE_ENABLE:
|
||||||
openAudioOutput(audioOutputArray[i], &audio_format);
|
openAudioOutput(&audioOutputArray[i], &audio_format);
|
||||||
audioDeviceStates[i] = DEVICE_ON;
|
audioDeviceStates[i] = DEVICE_ON;
|
||||||
/* there's no point in dropping audio for something
|
/* there's no point in dropping audio for something
|
||||||
* we just enabled */
|
* we just enabled */
|
||||||
break;
|
break;
|
||||||
case DEVICE_DISABLE:
|
case DEVICE_DISABLE:
|
||||||
dropBufferedAudioOutput(audioOutputArray[i]);
|
dropBufferedAudioOutput(&audioOutputArray[i]);
|
||||||
closeAudioOutput(audioOutputArray[i]);
|
closeAudioOutput(&audioOutputArray[i]);
|
||||||
audioDeviceStates[i] = DEVICE_OFF;
|
audioDeviceStates[i] = DEVICE_OFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -421,7 +418,7 @@ void closeAudioDevice(void)
|
|||||||
audioBufferSize = 0;
|
audioBufferSize = 0;
|
||||||
|
|
||||||
for (i = audioOutputArraySize; --i >= 0; ) {
|
for (i = audioOutputArraySize; --i >= 0; ) {
|
||||||
closeAudioOutput(audioOutputArray[i]);
|
closeAudioOutput(&audioOutputArray[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
audioOpened = 0;
|
audioOpened = 0;
|
||||||
@ -432,7 +429,7 @@ void sendMetadataToAudioDevice(MpdTag * tag)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = audioOutputArraySize; --i >= 0; ) {
|
for (i = audioOutputArraySize; --i >= 0; ) {
|
||||||
sendMetadataToAudioOutput(audioOutputArray[i], tag);
|
sendMetadataToAudioOutput(&audioOutputArray[i], tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +468,7 @@ void printAudioDevices(int fd)
|
|||||||
fdprintf(fd,
|
fdprintf(fd,
|
||||||
"outputid: %i\noutputname: %s\noutputenabled: %i\n",
|
"outputid: %i\noutputname: %s\noutputenabled: %i\n",
|
||||||
i,
|
i,
|
||||||
audioOutputArray[i]->name,
|
audioOutputArray[i].name,
|
||||||
audioDeviceStates[i] & 0x01);
|
audioDeviceStates[i] & 0x01);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -484,7 +481,7 @@ void saveAudioDevicesState(FILE *fp)
|
|||||||
for (i = 0; i < audioOutputArraySize; i++) {
|
for (i = 0; i < audioOutputArraySize; i++) {
|
||||||
fprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n",
|
fprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n",
|
||||||
audioDeviceStates[i] & 0x01,
|
audioDeviceStates[i] & 0x01,
|
||||||
audioOutputArray[i]->name);
|
audioOutputArray[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +507,7 @@ void readAudioDevicesState(FILE *fp)
|
|||||||
goto errline;
|
goto errline;
|
||||||
|
|
||||||
for (i = audioOutputArraySize; --i >= 0; ) {
|
for (i = audioOutputArraySize; --i >= 0; ) {
|
||||||
if (!strcmp(name, audioOutputArray[i]->name)) {
|
if (!strcmp(name, audioOutputArray[i].name)) {
|
||||||
/* devices default to on */
|
/* devices default to on */
|
||||||
if (!atoi(c))
|
if (!atoi(c))
|
||||||
audioDeviceStates[i] = DEVICE_DISABLE;
|
audioDeviceStates[i] = DEVICE_DISABLE;
|
||||||
|
@ -66,9 +66,8 @@ void finishAudioOutputPlugins(void)
|
|||||||
if(bp) str = bp->value; \
|
if(bp) str = bp->value; \
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioOutput *newAudioOutput(ConfigParam * param)
|
int initAudioOutput(AudioOutput *ao, ConfigParam * param)
|
||||||
{
|
{
|
||||||
AudioOutput *ret = NULL;
|
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *format = NULL;
|
char *format = NULL;
|
||||||
@ -111,50 +110,47 @@ AudioOutput *newAudioOutput(ConfigParam * param)
|
|||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
WARNING("Unable to detect an audio device\n");
|
WARNING("Unable to detect an audio device\n");
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = "default detected output";
|
name = "default detected output";
|
||||||
type = plugin->name;
|
type = plugin->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = malloc(sizeof(AudioOutput));
|
ao->name = name;
|
||||||
ret->name = strdup(name);
|
ao->type = type;
|
||||||
ret->type = strdup(type);
|
ao->finishDriverFunc = plugin->finishDriverFunc;
|
||||||
ret->finishDriverFunc = plugin->finishDriverFunc;
|
ao->openDeviceFunc = plugin->openDeviceFunc;
|
||||||
ret->openDeviceFunc = plugin->openDeviceFunc;
|
ao->playFunc = plugin->playFunc;
|
||||||
ret->playFunc = plugin->playFunc;
|
ao->dropBufferedAudioFunc = plugin->dropBufferedAudioFunc;
|
||||||
ret->dropBufferedAudioFunc = plugin->dropBufferedAudioFunc;
|
ao->closeDeviceFunc = plugin->closeDeviceFunc;
|
||||||
ret->closeDeviceFunc = plugin->closeDeviceFunc;
|
ao->sendMetdataFunc = plugin->sendMetdataFunc;
|
||||||
ret->sendMetdataFunc = plugin->sendMetdataFunc;
|
ao->open = 0;
|
||||||
ret->open = 0;
|
|
||||||
|
|
||||||
ret->convertAudioFormat = 0;
|
ao->convertAudioFormat = 0;
|
||||||
ret->sameInAndOutFormats = 0;
|
ao->sameInAndOutFormats = 0;
|
||||||
ret->convBuffer = NULL;
|
ao->convBuffer = NULL;
|
||||||
ret->convBufferLen = 0;
|
ao->convBufferLen = 0;
|
||||||
|
|
||||||
memset(&ret->inAudioFormat, 0, sizeof(AudioFormat));
|
memset(&ao->inAudioFormat, 0, sizeof(AudioFormat));
|
||||||
memset(&ret->outAudioFormat, 0, sizeof(AudioFormat));
|
memset(&ao->outAudioFormat, 0, sizeof(AudioFormat));
|
||||||
memset(&ret->reqAudioFormat, 0, sizeof(AudioFormat));
|
memset(&ao->reqAudioFormat, 0, sizeof(AudioFormat));
|
||||||
|
|
||||||
if (format) {
|
if (format) {
|
||||||
ret->convertAudioFormat = 1;
|
ao->convertAudioFormat = 1;
|
||||||
|
|
||||||
if (0 != parseAudioConfig(&ret->reqAudioFormat, format)) {
|
if (0 != parseAudioConfig(&ao->reqAudioFormat, format)) {
|
||||||
ERROR("error parsing format at line %i\n", bp->line);
|
ERROR("error parsing format at line %i\n", bp->line);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyAudioFormat(&ret->outAudioFormat, &ret->reqAudioFormat);
|
copyAudioFormat(&ao->outAudioFormat, &ao->reqAudioFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugin->initDriverFunc(ret, param) != 0) {
|
if (plugin->initDriverFunc(ao, param) != 0)
|
||||||
free(ret);
|
return 0;
|
||||||
ret = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat)
|
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat)
|
||||||
@ -248,9 +244,6 @@ void finishAudioOutput(AudioOutput * audioOutput)
|
|||||||
audioOutput->finishDriverFunc(audioOutput);
|
audioOutput->finishDriverFunc(audioOutput);
|
||||||
if (audioOutput->convBuffer)
|
if (audioOutput->convBuffer)
|
||||||
free(audioOutput->convBuffer);
|
free(audioOutput->convBuffer);
|
||||||
free(audioOutput->type);
|
|
||||||
free(audioOutput->name);
|
|
||||||
free(audioOutput);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag)
|
void sendMetadataToAudioOutput(AudioOutput * audioOutput, MpdTag * tag)
|
||||||
|
@ -101,7 +101,7 @@ void finishAudioOutputPlugins();
|
|||||||
void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
|
void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
|
||||||
void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
|
void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
|
||||||
|
|
||||||
AudioOutput *newAudioOutput(ConfigParam * param);
|
int initAudioOutput(AudioOutput *, ConfigParam * param);
|
||||||
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat);
|
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat);
|
||||||
int playAudioOutput(AudioOutput * audioOutput, char *playChunk, int size);
|
int playAudioOutput(AudioOutput * audioOutput, char *playChunk, int size);
|
||||||
void dropBufferedAudioOutput(AudioOutput * audioOutput);
|
void dropBufferedAudioOutput(AudioOutput * audioOutput);
|
||||||
|
Loading…
Reference in New Issue
Block a user