| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   OSSaudiooutput.C - Audio output for Open Sound System
 -   Copyright (C) 2002-2005 Nasca Octavian Paul
 -   Author: Nasca Octavian Paul
 - 
 -   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.
 - 
 -   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
 - 
 - */
 - 
 - #include "OssEngine.h"
 - #include "../Misc/Util.h"
 - #include "../globals.h"
 - 
 - #include <cstring>
 - #include <stdlib.h>
 - #include <stdio.h>
 - #include <fcntl.h>
 - #include <sys/soundcard.h>
 - #include <sys/stat.h>
 - #include <sys/ioctl.h>
 - #include <unistd.h>
 - #include <iostream>
 - 
 - #include "InMgr.h"
 - 
 - using namespace std;
 - 
 - OssEngine::OssEngine()
 -     :AudioOut(), engThread(NULL)
 - {
 -     name = "OSS";
 - 
 -     midi.handle  = -1;
 -     audio.handle = -1;
 - 
 -     audio.smps = new short[synth->buffersize * 2];
 -     memset(audio.smps, 0, synth->bufferbytes);
 - }
 - 
 - OssEngine::~OssEngine()
 - {
 -     Stop();
 -     delete [] audio.smps;
 - }
 - 
 - bool OssEngine::openAudio()
 - {
 -     if(audio.handle != -1)
 -         return true;  //already open
 - 
 -     int snd_bitsize    = 16;
 -     int snd_fragment   = 0x00080009; //fragment size (?);
 -     int snd_stereo     = 1; //stereo;
 -     int snd_format     = AFMT_S16_LE;
 -     int snd_samplerate = synth->samplerate;
 - 
 -     audio.handle = open(config.cfg.LinuxOSSWaveOutDev, O_WRONLY, 0);
 -     if(audio.handle == -1) {
 -         cerr << "ERROR - I can't open the "
 -              << config.cfg.LinuxOSSWaveOutDev << '.' << endl;
 -         return false;
 -     }
 -     ioctl(audio.handle, SNDCTL_DSP_RESET, NULL);
 -     ioctl(audio.handle, SNDCTL_DSP_SETFMT, &snd_format);
 -     ioctl(audio.handle, SNDCTL_DSP_STEREO, &snd_stereo);
 -     ioctl(audio.handle, SNDCTL_DSP_SPEED, &snd_samplerate);
 -     ioctl(audio.handle, SNDCTL_DSP_SAMPLESIZE, &snd_bitsize);
 -     ioctl(audio.handle, SNDCTL_DSP_SETFRAGMENT, &snd_fragment);
 - 
 -     if(!getMidiEn()) {
 -         pthread_attr_t attr;
 -         pthread_attr_init(&attr);
 -         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 -         engThread = new pthread_t;
 -         pthread_create(engThread, &attr, _thread, this);
 -     }
 - 
 -     return true;
 - }
 - 
 - void OssEngine::stopAudio()
 - {
 -     int handle = audio.handle;
 -     if(handle == -1) //already closed
 -         return;
 -     audio.handle = -1;
 - 
 -     if(!getMidiEn() && engThread)
 -         pthread_join(*engThread, NULL);
 -     delete engThread;
 -     engThread = NULL;
 - 
 -     close(handle);
 - }
 - 
 - bool OssEngine::Start()
 - {
 -     bool good = true;
 - 
 -     if(!openAudio()) {
 -         cerr << "Failed to open OSS audio" << endl;
 -         good = false;
 -     }
 - 
 -     if(!openMidi()) {
 -         cerr << "Failed to open OSS midi" << endl;
 -         good = false;
 -     }
 - 
 -     return good;
 - }
 - 
 - void OssEngine::Stop()
 - {
 -     stopAudio();
 -     stopMidi();
 - }
 - 
 - void OssEngine::setMidiEn(bool nval)
 - {
 -     if(nval)
 -         openMidi();
 -     else
 -         stopMidi();
 - }
 - 
 - bool OssEngine::getMidiEn() const
 - {
 -     return midi.handle != -1;
 - }
 - 
 - void OssEngine::setAudioEn(bool nval)
 - {
 -     if(nval)
 -         openAudio();
 -     else
 -         stopAudio();
 - }
 - 
 - bool OssEngine::getAudioEn() const
 - {
 -     return audio.handle != -1;
 - }
 - 
 - bool OssEngine::openMidi()
 - {
 -     int handle = midi.handle;
 -     if(handle != -1)
 -         return true;  //already open
 - 
 -     handle = open(config.cfg.LinuxOSSSeqInDev, O_RDONLY, 0);
 - 
 -     if(-1 == handle)
 -         return false;
 -     midi.handle = handle;
 - 
 -     if(!getAudioEn()) {
 -         pthread_attr_t attr;
 -         pthread_attr_init(&attr);
 -         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 -         engThread = new pthread_t;
 -         pthread_create(engThread, &attr, _thread, this);
 -     }
 - 
 -     return true;
 - }
 - 
 - void OssEngine::stopMidi()
 - {
 -     int handle = midi.handle;
 -     if(handle == -1) //already closed
 -         return;
 - 
 -     midi.handle = -1;
 - 
 -     if(!getAudioEn() && engThread) {
 -         pthread_join(*engThread, NULL);
 -         delete engThread;
 -         engThread = NULL;
 -     }
 - 
 -     close(handle);
 - }
 - 
 - void *OssEngine::_thread(void *arg)
 - {
 -     return (static_cast<OssEngine *>(arg))->thread();
 - }
 - 
 - void *OssEngine::thread()
 - {
 -     unsigned char tmp[4] = {0, 0, 0, 0};
 -     set_realtime();
 -     while(getAudioEn() || getMidiEn()) {
 -         if(getAudioEn()) {
 -             const Stereo<float *> smps = getNext();
 - 
 -             float l, r;
 -             for(int i = 0; i < synth->buffersize; ++i) {
 -                 l = smps.l[i];
 -                 r = smps.r[i];
 - 
 -                 if(l < -1.0f)
 -                     l = -1.0f;
 -                 else
 -                 if(l > 1.0f)
 -                     l = 1.0f;
 -                 if(r < -1.0f)
 -                     r = -1.0f;
 -                 else
 -                 if(r > 1.0f)
 -                     r = 1.0f;
 - 
 -                 audio.smps[i * 2]     = (short int) (l * 32767.0f);
 -                 audio.smps[i * 2 + 1] = (short int) (r * 32767.0f);
 -             }
 -             int handle = audio.handle;
 -             if(handle != -1)
 -                 write(handle, audio.smps, synth->buffersize * 4);  // *2 because is 16 bit, again * 2 because is stereo
 -             else
 -                 break;
 -         }
 - 
 -         //Collect up to 30 midi events
 -         for(int k = 0; k < 30 && getMidiEn(); ++k) {
 -             static char escaped;
 - 
 -             memset(tmp, 0, 4);
 - 
 -             if(escaped) {
 -                 tmp[0]  = escaped;
 -                 escaped = 0;
 -             }
 -             else {
 -                 getMidi(tmp);
 -                 if(!(tmp[0] & 0x80))
 -                     continue;
 -             }
 -             getMidi(tmp + 1);
 -             if(tmp[1] & 0x80) {
 -                 escaped = tmp[1];
 -                 tmp[1]  = 0;
 -             }
 -             else {
 -                 getMidi(tmp + 2);
 -                 if(tmp[2] & 0x80) {
 -                     escaped = tmp[2];
 -                     tmp[2]  = 0;
 -                 }
 -                 else {
 -                     getMidi(tmp + 3);
 -                     if(tmp[3] & 0x80) {
 -                         escaped = tmp[3];
 -                         tmp[3]  = 0;
 -                     }
 -                 }
 -             }
 -             midiProcess(tmp[0], tmp[1], tmp[2]);
 -         }
 -     }
 -     pthread_exit(NULL);
 -     return NULL;
 - }
 - 
 - void OssEngine::getMidi(unsigned char *midiPtr)
 - {
 -     read(midi.handle, midiPtr, 1);
 - }
 
 
  |