commit 9092e7a36562273c6581b5dfa2f3977dbb57edd0
parent aa88b902ca1ff87779c1172f4e35d58ca3b0fb88
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Sat, 1 Nov 2014 11:27:29 -0400
Fix OSS Under Linux
Diffstat:
3 files changed, 280 insertions(+), 263 deletions(-)
diff --git a/src/Nio/OssEngine.cpp b/src/Nio/OssEngine.cpp
@@ -212,7 +212,7 @@ bool OssEngine::openAudio()
const char *device = getenv("DSP_DEVICE");
if(device == NULL)
- device = config.cfg.LinuxOSSWaveOutDev;
+ device = config.cfg.LinuxOSSWaveOutDev;
/* NOTE: PIPEs and FIFOs can block when opening them */
audio.handle = open(device, O_WRONLY, O_NONBLOCK);
@@ -224,6 +224,9 @@ bool OssEngine::openAudio()
ioctl(audio.handle, SNDCTL_DSP_RESET, NULL);
/* Figure out the correct format first */
+#ifdef __linux__
+ int snd_format16 = AFMT_S16_NE;
+#else
#if defined(AFMT_S16_NE) && defined(AFMT_S32_NE)
int snd_format32 = AFMT_S32_NE;
int snd_format16 = AFMT_S16_NE;
@@ -239,15 +242,21 @@ bool OssEngine::openAudio()
int snd_format32 = AFMT_S32_LE;
int snd_format16 = AFMT_S16_LE;
#endif
+#endif
- if (ioctl(audio.handle, SNDCTL_DSP_SETFMT, &snd_format32) == 0) {
- audio.is32bit = true;
+#ifdef __linux__
+#define SND_32_INIT -1
+#else
+#define SND_32_INIT ioctl(audio.handle, SNDCTL_DSP_SETFMT, &snd_format32)
+#endif
+ if (SND_32_INIT == 0) {
+ audio.is32bit = true;
} else if (ioctl(audio.handle, SNDCTL_DSP_SETFMT, &snd_format16) == 0) {
- audio.is32bit = false;
+ audio.is32bit = false;
} else {
- cerr << "ERROR - I cannot set DSP format for "
- << device << '.' << endl;
- goto error;
+ cerr << "ERROR - I cannot set DSP format for "
+ << device << '.' << endl;
+ goto error;
}
ioctl(audio.handle, SNDCTL_DSP_STEREO, &snd_stereo);
ioctl(audio.handle, SNDCTL_DSP_SPEED, &snd_samplerate);
@@ -359,7 +368,7 @@ bool OssEngine::openMidi()
const char *device = getenv("MIDI_DEVICE");
if(device == NULL)
- device = config.cfg.LinuxOSSSeqInDev;
+ device = config.cfg.LinuxOSSSeqInDev;
/* NOTE: PIPEs and FIFOs can block when opening them */
handle = open(device, O_RDONLY, O_NONBLOCK);
@@ -431,13 +440,13 @@ void *OssEngine::audioThreadCb()
if(r > 1.0f)
r = 1.0f;
- if (audio.is32bit) {
- audio.smps.ps32[i * 2] = (int) (l * 2147483647.0f);
- audio.smps.ps32[i * 2 + 1] = (int) (r * 2147483647.0f);
- } else { /* 16bit */
- audio.smps.ps16[i * 2] = (short int) (l * 32767.0f);
- audio.smps.ps16[i * 2 + 1] = (short int) (r * 32767.0f);
- }
+ if (audio.is32bit) {
+ audio.smps.ps32[i * 2] = (int) (l * 2147483647.0f);
+ audio.smps.ps32[i * 2 + 1] = (int) (r * 2147483647.0f);
+ } else {/* 16bit */
+ audio.smps.ps16[i * 2] = (short int) (l * 32767.0f);
+ audio.smps.ps16[i * 2 + 1] = (short int) (r * 32767.0f);
+ }
}
int error;
@@ -446,7 +455,7 @@ void *OssEngine::audioThreadCb()
int handle = audio.handle;
if(handle == -1)
goto done;
- error = write(handle, audio.smps.ps32, audio.buffersize);
+ error = write(handle, audio.smps.ps32, audio.buffersize);
} while (error == -1 && errno == EINTR);
if(error == -1)
diff --git a/src/Nio/OssMultiEngine.cpp b/src/Nio/OssMultiEngine.cpp
@@ -1,21 +1,21 @@
/*
- ZynAddSubFX - a software synthesizer
+ ZynAddSubFX - a software synthesizer
- OssMultiEngine.cpp - Multi channel audio output for Open Sound System
- Copyright (C) 2014 Hans Petter Selasky
+ OssMultiEngine.cpp - Multi channel audio output for Open Sound System
+ Copyright (C) 2014 Hans Petter Selasky
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License
- as published by the Free Software Foundation.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License
+ as published by the Free Software Foundation.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License (version 2 or later) for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License (version 2 or later) for more details.
- You should have received a copy of the GNU General Public License (version 2)
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU General Public License (version 2)
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -45,250 +45,258 @@ using namespace std;
OssMultiEngine :: OssMultiEngine()
{
- /* setup variables */
- name = "OSS-MULTI";
- audioThread = 0;
- handle = -1;
- channels = 0;
- en = false;
- is32bit = false;
- buffersize = 0;
-
- /* compute worst case buffer size */
- maxbuffersize = NUM_MIDI_PARTS * sizeof(int) * synth->buffersize * 2;
- /* allocate buffer */
- smps.ps32 = new int[maxbuffersize / sizeof(int)];
- memset(smps.ps32, 0, maxbuffersize);
+ /* setup variables */
+ name = "OSS-MULTI";
+ audioThread = 0;
+ handle = -1;
+ channels = 0;
+ en = false;
+ is32bit = false;
+ buffersize = 0;
+
+ /* compute worst case buffer size */
+ maxbuffersize = NUM_MIDI_PARTS * sizeof(int) * synth->buffersize * 2;
+ /* allocate buffer */
+ smps.ps32 = new int[maxbuffersize / sizeof(int)];
+ memset(smps.ps32, 0, maxbuffersize);
}
OssMultiEngine :: ~OssMultiEngine()
{
- Stop();
- delete [] smps.ps32;
+ Stop();
+ delete [] smps.ps32;
}
-bool
+ bool
OssMultiEngine :: openAudio()
{
- int snd_samplerate;
- int snd_format32;
- int snd_format16;
- int snd_fragment;
- int x;
-
- /* check if already open */
- if (handle != -1)
- return (true);
-
- const char *device = getenv("DSP_DEVICE");
- if(device == 0)
- device = config.cfg.LinuxOSSWaveOutDev;
-
- /* NOTE: PIPEs and FIFOs can block when opening them */
- handle = open(device, O_WRONLY, O_NONBLOCK);
- if (handle == -1) {
- cerr << "ERROR - I can't open the "
- << device << '.' << endl;
- return (false);
- }
- ioctl(handle, SNDCTL_DSP_RESET, 0);
-
- /* Figure out the correct format first */
+ int snd_samplerate;
+ int snd_fragment;
+ int x;
+
+ /* check if already open */
+ if (handle != -1)
+ return (true);
+
+ const char *device = getenv("DSP_DEVICE");
+ if(device == 0)
+ device = config.cfg.LinuxOSSWaveOutDev;
+
+ /* NOTE: PIPEs and FIFOs can block when opening them */
+ handle = open(device, O_WRONLY, O_NONBLOCK);
+ if (handle == -1) {
+ cerr << "ERROR - I can't open the "
+ << device << '.' << endl;
+ return (false);
+ }
+ ioctl(handle, SNDCTL_DSP_RESET, 0);
+
+ /* Figure out the correct format first */
+#ifdef __linux__
+ int snd_format16 = AFMT_S16_NE;
+#else
#if defined(AFMT_S16_NE) && defined(AFMT_S32_NE)
- snd_format32 = AFMT_S32_NE;
- snd_format16 = AFMT_S16_NE;
+ int snd_format32 = AFMT_S32_NE;
+ int snd_format16 = AFMT_S16_NE;
#elif defined(BYTE_ORDER) && defined(LITTLE_ENDIAN)
#if BYTE_ORDER == LITTLE_ENDIAN
- snd_format32 = AFMT_S32_LE;
- snd_format16 = AFMT_S16_LE;
+ int snd_format32 = AFMT_S32_LE;
+ int snd_format16 = AFMT_S16_LE;
#else
- snd_format32 = AFMT_S32_BE;
- snd_format16 = AFMT_S16_BE;
+ int snd_format32 = AFMT_S32_BE;
+ int snd_format16 = AFMT_S16_BE;
#endif
#else
- snd_format32 = AFMT_S32_LE;
- snd_format16 = AFMT_S16_LE;
+ int snd_format32 = AFMT_S32_LE;
+ int snd_format16 = AFMT_S16_LE;
+#endif
#endif
- if (ioctl(handle, SNDCTL_DSP_SETFMT, &snd_format32) == 0) {
- is32bit = true;
- } else if (ioctl(handle, SNDCTL_DSP_SETFMT, &snd_format16) == 0) {
- is32bit = false;
- } else {
- cerr << "ERROR - Cannot set DSP format for "
- << device << '.' << endl;
- goto error;
- }
- for (x = NUM_MIDI_PARTS * 2; x >= 2; x -= 2) {
- if (ioctl(handle, SNDCTL_DSP_CHANNELS, &x) == 0)
- break;
- }
- if (x == 0) {
- cerr << "ERROR - Cannot set DSP channels for "
- << device << '.' << endl;
- goto error;
- }
- channels = x;
-
- snd_samplerate = synth->samplerate;
-
- ioctl(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 samples */
- buffersize = 2 * synth->buffersize * channels;
- if (is32bit)
- buffersize *= 2;
-
- for (x = 4; x < 20; x++) {
- if ((1 << x) >= buffersize)
- break;
- }
-
- snd_fragment = 0x20000 | x; /* 2x buffer */
-
- ioctl(handle, SNDCTL_DSP_SETFRAGMENT, &snd_fragment);
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- pthread_create(&audioThread, &attr, _audioThreadCb, this);
-
- return (true);
+#ifdef __linux__
+#define SND_32_INIT -1
+#else
+#define SND_32_INIT ioctl(audio.handle, SNDCTL_DSP_SETFMT, &snd_format32)
+#endif
+
+ if (SND_32_INIT == 0) {
+ is32bit = true;
+ } else if (ioctl(handle, SNDCTL_DSP_SETFMT, &snd_format16) == 0) {
+ is32bit = false;
+ } else {
+ cerr << "ERROR - Cannot set DSP format for "
+ << device << '.' << endl;
+ goto error;
+ }
+ for (x = NUM_MIDI_PARTS * 2; x >= 2; x -= 2) {
+ if (ioctl(handle, SNDCTL_DSP_CHANNELS, &x) == 0)
+ break;
+ }
+ if (x == 0) {
+ cerr << "ERROR - Cannot set DSP channels for "
+ << device << '.' << endl;
+ goto error;
+ }
+ channels = x;
+
+ snd_samplerate = synth->samplerate;
+
+ ioctl(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 samples */
+ buffersize = 2 * synth->buffersize * channels;
+ if (is32bit)
+ buffersize *= 2;
+
+ for (x = 4; x < 20; x++) {
+ if ((1 << x) >= buffersize)
+ break;
+ }
+
+ snd_fragment = 0x20000 | x; /* 2x buffer */
+
+ ioctl(handle, SNDCTL_DSP_SETFRAGMENT, &snd_fragment);
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ pthread_create(&audioThread, &attr, _audioThreadCb, this);
+
+ return (true);
error:
- close(handle);
- handle = -1;
- return (false);
+ close(handle);
+ handle = -1;
+ return (false);
}
-void
+ void
OssMultiEngine :: stopAudio()
{
- int fd = handle;
+ int fd = handle;
- /* check if already closed */
- if (fd == -1)
- return;
- handle = -1;
+ /* check if already closed */
+ if (fd == -1)
+ return;
+ handle = -1;
- /* close handle first, so that write() exits */
- close(fd);
+ /* close handle first, so that write() exits */
+ close(fd);
- pthread_join(audioThread, 0);
- audioThread = 0;
+ pthread_join(audioThread, 0);
+ audioThread = 0;
}
-bool
+ bool
OssMultiEngine :: Start()
{
- return (openAudio());
+ return (openAudio());
}
-void
+ void
OssMultiEngine :: Stop()
{
- stopAudio();
+ stopAudio();
}
-void
+ void
OssMultiEngine :: setAudioEn(bool enable)
{
- if (enable)
- openAudio();
- else
- stopAudio();
+ if (enable)
+ openAudio();
+ else
+ stopAudio();
}
bool
OssMultiEngine :: getAudioEn() const
{
- return (handle != -1);
+ return (handle != -1);
}
-void *
+ void *
OssMultiEngine :: _audioThreadCb(void *arg)
{
- return (static_cast<OssMultiEngine *>(arg))->audioThreadCb();
+ return (static_cast<OssMultiEngine *>(arg))->audioThreadCb();
}
-void *
+ void *
OssMultiEngine :: audioThreadCb()
{
- /*
- * In case the audio device is a PIPE/FIFO, we need to ignore
- * any PIPE signals:
- */
- signal(SIGPIPE, SIG_IGN);
-
- set_realtime();
-
- while(getAudioEn()) {
- int error;
- float l;
- float r;
- int x;
- int y;
-
- /* get next buffer */
- getNext();
-
- /* extract audio from the "channels / 2" first parts */
- for (x = 0; x != channels; x += 2) {
- Part *part = middleware->spawnMaster()->part[x / 2];
-
- if (is32bit) {
- for (y = 0; y != synth->buffersize; y++) {
- l = part->partoutl[y];
- if (l < -1.0f)
- l = -1.0f;
- else if (l > 1.0f)
- l = 1.0f;
- smps.ps32[y * channels + x] = (int)(l * 2147483647.0f);
- r = part->partoutr[y];
- if (r < -1.0f)
- r = -1.0f;
- else if (r > 1.0f)
- r = 1.0f;
- smps.ps32[y * channels + x + 1] = (int)(r * 2147483647.0f);
- }
- } else {
- for (y = 0; y != synth->buffersize; y++) {
- l = part->partoutl[y];
- if (l < -1.0f)
- l = -1.0f;
- else if (l > 1.0f)
- l = 1.0f;
- smps.ps16[y * channels + x] = (short int)(l * 32767.0f);
- r = part->partoutr[y];
- if (r < -1.0f)
- r = -1.0f;
- else if (r > 1.0f)
- r = 1.0f;
- smps.ps16[y * channels + x + 1] = (short int)(r * 32767.0f);
- }
- }
- }
-
- /* write audio buffer to DSP device */
- do {
- /* make a copy of handle, in case of OSS audio disable */
- int fd = handle;
- if (fd == -1)
- goto done;
- error = write(fd, smps.ps32, buffersize);
- } while (error == -1 && errno == EINTR);
-
- if(error == -1)
- goto done;
- }
+ /*
+ * In case the audio device is a PIPE/FIFO, we need to ignore
+ * any PIPE signals:
+ */
+ signal(SIGPIPE, SIG_IGN);
+
+ set_realtime();
+
+ while(getAudioEn()) {
+ int error;
+ float l;
+ float r;
+ int x;
+ int y;
+
+ /* get next buffer */
+ getNext();
+
+ /* extract audio from the "channels / 2" first parts */
+ for (x = 0; x != channels; x += 2) {
+ Part *part = middleware->spawnMaster()->part[x / 2];
+
+ if (is32bit) {
+ for (y = 0; y != synth->buffersize; y++) {
+ l = part->partoutl[y];
+ if (l < -1.0f)
+ l = -1.0f;
+ else if (l > 1.0f)
+ l = 1.0f;
+ smps.ps32[y * channels + x] = (int)(l * 2147483647.0f);
+ r = part->partoutr[y];
+ if (r < -1.0f)
+ r = -1.0f;
+ else if (r > 1.0f)
+ r = 1.0f;
+ smps.ps32[y * channels + x + 1] = (int)(r * 2147483647.0f);
+ }
+ } else {
+ for (y = 0; y != synth->buffersize; y++) {
+ l = part->partoutl[y];
+ if (l < -1.0f)
+ l = -1.0f;
+ else if (l > 1.0f)
+ l = 1.0f;
+ smps.ps16[y * channels + x] = (short int)(l * 32767.0f);
+ r = part->partoutr[y];
+ if (r < -1.0f)
+ r = -1.0f;
+ else if (r > 1.0f)
+ r = 1.0f;
+ smps.ps16[y * channels + x + 1] = (short int)(r * 32767.0f);
+ }
+ }
+ }
+
+ /* write audio buffer to DSP device */
+ do {
+ /* make a copy of handle, in case of OSS audio disable */
+ int fd = handle;
+ if (fd == -1)
+ goto done;
+ error = write(fd, smps.ps32, buffersize);
+ } while (error == -1 && errno == EINTR);
+
+ if(error == -1)
+ goto done;
+ }
done:
- pthread_exit(0);
- return (0);
+ pthread_exit(0);
+ return (0);
}
diff --git a/src/Nio/OssMultiEngine.h b/src/Nio/OssMultiEngine.h
@@ -1,21 +1,21 @@
/*
- ZynAddSubFX - a software synthesizer
+ ZynAddSubFX - a software synthesizer
- OssMultiEngine.h - Multi channel audio output for Open Sound System
- Copyright (C) 2014 Hans Petter Selasky
+ OssMultiEngine.h - Multi channel audio output for Open Sound System
+ Copyright (C) 2014 Hans Petter Selasky
- This program is free software; you can redistribute it and/or modify
- it under the terms of version 2 of the GNU General Public License
- as published by the Free Software Foundation.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License
+ as published by the Free Software Foundation.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License (version 2 or later) for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License (version 2 or later) for more details.
- You should have received a copy of the GNU General Public License (version 2)
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ You should have received a copy of the GNU General Public License (version 2)
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -28,40 +28,40 @@
class OssMultiEngine : public AudioOut
{
-public:
- OssMultiEngine();
- ~OssMultiEngine();
+ public:
+ OssMultiEngine();
+ ~OssMultiEngine();
- bool Start();
- void Stop();
+ bool Start();
+ void Stop();
- void setAudioEn(bool nval);
- bool getAudioEn() const;
+ void setAudioEn(bool nval);
+ bool getAudioEn() const;
-protected:
- void *audioThreadCb();
- static void *_audioThreadCb(void *arg);
+ protected:
+ void *audioThreadCb();
+ static void *_audioThreadCb(void *arg);
-private:
- pthread_t audioThread;
+ private:
+ pthread_t audioThread;
- /* Audio */
- bool openAudio();
- void stopAudio();
+ /* Audio */
+ bool openAudio();
+ void stopAudio();
- int handle;
- int maxbuffersize;
- int buffersize;
- int channels;
+ int handle;
+ int maxbuffersize;
+ int buffersize;
+ int channels;
- union {
- /* Samples to be sent to soundcard */
- short int *ps16;
- int *ps32;
- } smps;
+ union {
+ /* Samples to be sent to soundcard */
+ short int *ps16;
+ int *ps32;
+ } smps;
- bool en;
- bool is32bit;
+ bool en;
+ bool is32bit;
};
#endif