aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio.c
diff options
context:
space:
mode:
authorWarren Dukes <warren.dukes@gmail.com>2004-11-09 00:13:42 +0000
committerWarren Dukes <warren.dukes@gmail.com>2004-11-09 00:13:42 +0000
commitb7315f839161d940e0e9ae1363d1e74b15e73d72 (patch)
treeb959573c824f036997988a7fd6c17f46d8eb87ed /src/audio.c
parent9b03731c869ad4ca7c19cda3558d3a47855743da (diff)
downloadmpd-b7315f839161d940e0e9ae1363d1e74b15e73d72.tar.gz
mpd-b7315f839161d940e0e9ae1363d1e74b15e73d72.tar.xz
mpd-b7315f839161d940e0e9ae1363d1e74b15e73d72.zip
add a buffer to audio layer, so we only send data to audio devices 32 times per second
git-svn-id: https://svn.musicpd.org/mpd/trunk@2553 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to '')
-rw-r--r--src/audio.c66
1 files changed, 53 insertions, 13 deletions
diff --git a/src/audio.c b/src/audio.c
index 24d815961..47c1880cc 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -42,6 +42,10 @@ static mpd_sint8 myAudioDevicesEnabled[AUDIO_MAX_DEVICES];
static mpd_uint8 audioOpened = 0;
+static mpd_sint32 audioBufferSize = 0;
+static char * audioBuffer = NULL;
+static mpd_sint32 audioBufferPos = 0;
+
void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
if(!src) return;
@@ -221,6 +225,32 @@ inline void syncAudioDevicesEnabledArrays() {
}
}
+static int flushAudioBuffer() {
+ int ret = -1;
+ int i;
+
+ if(audioBufferPos == 0) return 0;
+
+ if(0 != memcmp(pdAudioDevicesEnabled, myAudioDevicesEnabled,
+ AUDIO_MAX_DEVICES))
+ {
+ syncAudioDevicesEnabledArrays();
+ }
+
+ for(i = 0; i < audioOutputArraySize; i++) {
+ if(!myAudioDevicesEnabled[i]) continue;
+ if(0 == playAudioOutput(audioOutputArray[i], audioBuffer,
+ audioBufferPos))
+ {
+ ret = 0;
+ }
+ }
+
+ audioBufferPos = 0;
+
+ return ret;
+}
+
int openAudioDevice(AudioFormat * audioFormat) {
int isCurrentFormat = isCurrentAudioFormat(audioFormat);
int ret = -1;
@@ -228,8 +258,12 @@ int openAudioDevice(AudioFormat * audioFormat) {
if(!audioOutputArray) return -1;
- if(!isCurrentFormat) {
+ if(!audioOpened || !isCurrentFormat) {
+ flushAudioBuffer();
copyAudioFormat(&audio_format, audioFormat);
+ audioBufferSize = (audio_format.bits/8)*audio_format.channels;
+ audioBufferSize*= audio_format.sampleRate >> 5;
+ audioBuffer = realloc(audioBuffer, audioBufferSize);
}
syncAudioDevicesEnabledArrays();
@@ -252,23 +286,23 @@ int openAudioDevice(AudioFormat * audioFormat) {
}
int playAudio(char * playChunk, int size) {
- int ret = -1;
- int i;
+ int send;
+
+ while(size > 0) {
+ send = audioBufferSize-audioBufferPos;
+ send = send < size ? send : size;
- if(0 != memcmp(pdAudioDevicesEnabled, myAudioDevicesEnabled,
- AUDIO_MAX_DEVICES))
- {
- syncAudioDevicesEnabledArrays();
- }
+ memcpy(audioBuffer+audioBufferPos, playChunk, send);
+ audioBufferPos += send;
+ size -= send;
+ playChunk+= send;
- for(i = 0; i < audioOutputArraySize; i++) {
- if(!myAudioDevicesEnabled[i]) continue;
- if(0 == playAudioOutput(audioOutputArray[i], playChunk, size)) {
- ret = 0;
+ if(audioBufferPos == audioBufferSize) {
+ if( flushAudioBuffer() < 0 ) return -1;
}
}
- return ret;
+ return 0;
}
int isAudioDeviceOpen() {
@@ -278,6 +312,12 @@ int isAudioDeviceOpen() {
void closeAudioDevice() {
int i;
+ flushAudioBuffer();
+
+ free(audioBuffer);
+ audioBuffer = NULL;
+ audioBufferSize = 0;
+
for(i = 0; i < audioOutputArraySize; i++) {
closeAudioOutput(audioOutputArray[i]);
}