commit 5bc4061568c52bb0629981862ba9009ddf1f041a
parent 221bd7d5f94f271f044d875985d596c45d16ba80
Author: Hans Petter Selasky <hps@selasky.org>
Date: Thu, 30 Oct 2014 08:11:49 +0100
OSS improvements:
- Assert the specified sample rate has been set for the OSS audio
backend.
- Improve OSS audio backend latency, by computing the fragment size
corresponding to the audio buffer size.
Signed-off-by: Hans Petter Selasky <hps@selasky.org>
Diffstat:
2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/src/Nio/OssEngine.cpp b/src/Nio/OssEngine.cpp
@@ -201,10 +201,12 @@ OssEngine::~OssEngine()
bool OssEngine::openAudio()
{
+ int x;
+
if(audio.handle != -1)
return true; //already open
- int snd_fragment = 0x00080009; //fragment size (?);
+ int snd_fragment;
int snd_stereo = 1; //stereo;
int snd_samplerate = synth->samplerate;
@@ -245,12 +247,30 @@ bool OssEngine::openAudio()
} else {
cerr << "ERROR - I cannot set DSP format for "
<< device << '.' << endl;
- close(audio.handle);
- audio.handle = -1;
- return false;
+ goto error;
}
ioctl(audio.handle, SNDCTL_DSP_STEREO, &snd_stereo);
ioctl(audio.handle, SNDCTL_DSP_SPEED, &snd_samplerate);
+
+ if (snd_samplerate != (int)synth->samplerate) {
+ cerr << "ERROR - Cannot set samplerate for "
+ << device << ". " << snd_samplerate
+ << " != " << synth->samplerate << endl;
+ goto error;
+ }
+
+ /* compute buffer size for 16-bit stereo samples */
+ audio.buffersize = 4 * synth->buffersize;
+ if (audio.is32bit)
+ audio.buffersize *= 2;
+
+ for (x = 4; x < 20; x++) {
+ if ((1 << x) >= audio.buffersize)
+ break;
+ }
+
+ snd_fragment = 0x20000 | x; /* 2x buffer */
+
ioctl(audio.handle, SNDCTL_DSP_SETFRAGMENT, &snd_fragment);
pthread_attr_t attr;
@@ -260,6 +280,11 @@ bool OssEngine::openAudio()
pthread_create(audioThread, &attr, _audioThreadCb, this);
return true;
+
+error:
+ close(audio.handle);
+ audio.handle = -1;
+ return false;
}
void OssEngine::stopAudio()
@@ -421,13 +446,7 @@ void *OssEngine::audioThreadCb()
int handle = audio.handle;
if(handle == -1)
goto done;
- if (audio.is32bit) {
- /* 4x because it is 32 bit, again 2x because it is stereo */
- error = write(handle, audio.smps.ps32, synth->buffersize * 8);
- } else {
- /* 2x because it is 16 bit, again 2x because it is stereo */
- error = write(handle, audio.smps.ps16, synth->buffersize * 4);
- }
+ error = write(handle, audio.smps.ps32, audio.buffersize);
} while (error == -1 && errno == EINTR);
if(error == -1)
diff --git a/src/Nio/OssEngine.h b/src/Nio/OssEngine.h
@@ -74,6 +74,7 @@ class OssEngine:public AudioOut, MidiIn
struct audio {
int handle;
+ int buffersize;
union {
/* Samples to be sent to soundcard */
short int *ps16;