zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit 3f1e87128362eb2ea25c2458ecf43af486aecf4c
parent 3f266b752f4b73bc288e19d3e12fbb2594ff50ab
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Tue, 22 Dec 2009 12:42:32 -0800

Nio: Added Basic PortAudio driver

- Added port audio driver
- Added UI for driver
- Added conditional compiling for driver GUIs

Diffstat:
Msrc/CMakeLists.txt | 19+++++++++++++------
Msrc/Nio/CMakeLists.txt | 11+++++------
Msrc/Nio/OutMgr.cpp | 10++++++++++
Asrc/Nio/PaEngine.cpp | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Nio/PaEngine.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/UI/NioUI.cpp | 24+++++++++++++++++++++---
Msrc/UI/NioUI.h | 2+-
7 files changed, 213 insertions(+), 16 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -30,6 +30,8 @@ SET (JackEnable ${JACK_FOUND} CACHE BOOL "Enable support for JACK Audio Connection toolKit") SET (OssEnable ${ALSA_FOUND} CACHE BOOL #TODO perhaps check for /dev/dsp "Enable support for Open Sound System") +SET (PaEnable ${PORTAUDIO_FOUND} CACHE BOOL + "Enable support for Port Audio System") # Now, handle the incoming settings and set define flags/variables based # on this @@ -54,6 +56,8 @@ elseif(DefaultOutput STREQUAL oss) add_definitions(-DOSS_DEFAULT=1) elseif(DefaultOutput STREQUAL jack) add_definitions(-DJACK_DEFAULT=1) +elseif(DefaultOutput STREQUAL portaudio) + add_definitions(-DPORTAUDIO_DEFAULT=1) endif() @@ -65,16 +69,25 @@ if(AlsaEnable) list(APPEND AUDIO_LIBRARIES ${ASOUND_LIBRARY}) add_definitions(-DALSA=1) endif(AlsaEnable) + if(JackEnable) list(APPEND AUDIO_LIBRARIES ${JACK_LIBRARIES}) add_definitions(-DJACK=1) endif(JackEnable) + if(OssEnable) add_definitions(-DOSSAUDIOOUT) list(APPEND AUDIO_LIBRARIES ${ASOUND_LIBRARY}) add_definitions(-DOSS=1) endif(OssEnable) +if(PaEnable) + include_directories(${PORTAUDIO_INCLUDE_DIR}) + add_definitions(-DPORTAUDIO=1) + list(APPEND AUDIO_LIBRARIES ${PORTAUDIO_LIBRARIES}) +endif() + + if(AlsaMidiOutput) add_definitions(-DOSSAUDIOOUT) set(AUDIO_LIBRARIES ${AUDIO_LIBRARIES} ${ASOUND_LIBRARY}) @@ -90,12 +103,6 @@ if(JackOutput) set(AUDIO_LIBRARIES ${AUDIO_LIBRARIES} ${JACK_LIBRARIES}) endif() -if(PortAudioOutput) - include_directories(${PORTAUDIO_INCLUDE_DIR}) - add_definitions(-DPAAUDIOOUT) - set(AUDIO_LIBRARIES ${AUDIO_LIBRARIES} ${PORTAUDIO_LIBRARIES}) -endif() - add_definitions(-DFFTW_VERSION_${FFTW_VERSION} -DASM_F2I_YES -g #TODO #todo put in a better location diff --git a/src/Nio/CMakeLists.txt b/src/Nio/CMakeLists.txt @@ -18,12 +18,11 @@ if(JackEnable) list(APPEND zynaddsubfx_nio_lib ${JACK_LIBRARIES}) endif(JackEnable) -#Uncomment when Port Audio is integrated -#if(PortAudioOutput) -# include_directories(${PORTAUDIO_INCLUDE_DIR}) -# list(APPEND zynaddsubfx_nio_SRCS PaEngine.cpp) -# list(zynaddsubfx_nio_lib ${PORTAUDIO_LIBRARIES}) -#endif(PortAudioOutput) +if(PaEnable) + include_directories(${PORTAUDIO_INCLUDE_DIR}) + list(APPEND zynaddsubfx_nio_SRCS PaEngine.cpp) + list(APPEND zynaddsubfx_nio_lib ${PORTAUDIO_LIBRARIES}) +endif(PaEnable) if(AlsaEnable) list(APPEND zynaddsubfx_nio_SRCS AlsaEngine.cpp) diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp @@ -13,6 +13,9 @@ #if JACK #include "JackEngine.h" #endif +#if PORTAUDIO +#include "PaEngine.h" +#endif using namespace std; @@ -55,6 +58,13 @@ OutMgr::OutMgr(Master *nmaster) managedOuts["JACK"] = new JackEngine(this); #endif #endif +#if PORTAUDIO +#if PORTAUDIO_DEFAULT + managedOuts["PA"] = defaultOut = new PaEngine(this); +#else + managedOuts["PA"] = new PaEngine(this); +#endif +#endif defaultOut->out(Stereo<Sample>(Sample(SOUND_BUFFER_SIZE * 20, 0.0), Sample(SOUND_BUFFER_SIZE * 20, 0.0))); diff --git a/src/Nio/PaEngine.cpp b/src/Nio/PaEngine.cpp @@ -0,0 +1,109 @@ +/* + ZynAddSubFX - a software synthesizer + + PaEngine.cpp - Audio output for PortAudio + Copyright (C) 2002 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 "PaEngine.h" +#include "../Samples/Sample.h" +#include <iostream> + +using namespace std; + +PaEngine::PaEngine(OutMgr *out) + :AudioOut(out) +{} + + +PaEngine::~PaEngine() +{ + Stop(); +} + +bool PaEngine::Start() +{ + if(enabled()) + return true; + enabled = true; + Pa_Initialize(); + + PaStreamParameters outputParameters; + outputParameters.device = Pa_GetDefaultOutputDevice(); + if (outputParameters.device == paNoDevice) { + cerr << "Error: No default output device." << endl; + Pa_Terminate(); + return false; + } + outputParameters.channelCount = 2; /* stereo output */ + outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ + outputParameters.suggestedLatency = + Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; + outputParameters.hostApiSpecificStreamInfo = NULL; + + + Pa_OpenStream(&stream, + NULL, + &outputParameters, + SAMPLE_RATE, + SOUND_BUFFER_SIZE, + NULL, + PAprocess, + (void *) this); + Pa_StartStream(stream); + return true; +} + +int PaEngine::PAprocess(const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags flags, + void *userData) +{ + return static_cast<PaEngine *>(userData)->process((float *) outputBuffer, + framesPerBuffer); +} + +int PaEngine::process(float *out, unsigned long framesPerBuffer) +{ + + const Stereo<Sample> smp = getNext(); + + if(framesPerBuffer != smp.l().size()) + cerr << "Bug: PaEngine::process SOUND_BUFFER_SIZE!=framesPerBuffer" + << framesPerBuffer << ' ' << smp.l().size() << endl; + + for(int i = 0; i < framesPerBuffer; i++) { + if(i >= smp.l().size()) + break;//this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE + *out++ = smp.l()[i]; + *out++ = smp.r()[i]; + } + + return 0; +} + +void PaEngine::Stop() +{ + if(!enabled()) + return; + enabled = false; + Pa_StopStream(stream); + Pa_CloseStream(stream); + Pa_Terminate(); +} + diff --git a/src/Nio/PaEngine.h b/src/Nio/PaEngine.h @@ -0,0 +1,54 @@ +/* + ZynAddSubFX - a software synthesizer + + PAaudiooutput.h - Audio output for PortAudio + Copyright (C) 2002 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 + +*/ +#ifndef PA_ENGINE_H +#define PA_ENGINE_H + +#include <portaudio.h> + +#include "../globals.h" +#include "AudioOut.h" + +class PaEngine: public AudioOut +{ + public: + PaEngine(OutMgr *out); + ~PaEngine(); + + bool Start(); + void Stop(); + + protected: + static int PAprocess(const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags flags, + void *userData); + int process(float *out, unsigned long framesPerBuffer); + private: + PaStream *stream; +}; + + +void PAaudiooutputinit(Master *master_); +void PAfinish(); + +#endif + diff --git a/src/UI/NioUI.cpp b/src/UI/NioUI.cpp @@ -9,17 +9,19 @@ NioUI::NioUI() :Fl_Window(200,100,400,400,"New IO Controls"), - groups(new Fl_Group*[4]), buttons(new Fl_Button*[4]) + groups(new Fl_Group*[5]), buttons(new Fl_Button*[4]) { groups[0]=NULL; groups[1]=NULL; groups[2]=NULL; groups[3]=NULL; + groups[4]=NULL; jackc = "JACK"; ossc = "OSS"; alsac = "ALSA"; nullc = "NULL"; + pac = "PA"; //hm, I appear to be leaking memory @@ -39,6 +41,7 @@ NioUI::NioUI() intro->wrap_mode(4, 40); } gen->end(); +#if OSS Fl_Group *oss = new Fl_Group(10,40,400,400-35,ossc); { Fl_Light_Button *enabler = new Fl_Light_Button(20,30,100,25,"Enable"); @@ -47,6 +50,8 @@ NioUI::NioUI() buttons[0] = enabler; } oss->end(); +#endif +#if ALSA Fl_Group *alsa = new Fl_Group(0,20,400,400-35,alsac); { Fl_Light_Button *enabler = new Fl_Light_Button(20,30,100,25,"Enable"); @@ -55,6 +60,8 @@ NioUI::NioUI() buttons[1] = enabler; } alsa->end(); +#endif +#if JACK Fl_Group *jack = new Fl_Group(0,20,400,400-35,jackc); { Fl_Light_Button *enabler = new Fl_Light_Button(20,30,100,25,"Enable"); @@ -63,12 +70,23 @@ NioUI::NioUI() buttons[2] = enabler; } jack->end(); +#endif +#if PORTAUDIO + Fl_Group *pa = new Fl_Group(0,20,400,400-35,pac); + { + Fl_Light_Button *enabler = new Fl_Light_Button(20,30,100,25,"Enable"); + enabler->callback(nioToggle, (void *)pa); + groups[3] = pa; + buttons[3] = enabler; + } + pa->end(); +#endif Fl_Group *null = new Fl_Group(0,20,400,400-35,nullc); { Fl_Light_Button *enabler = new Fl_Light_Button(20,30,100,25,"Enable"); enabler->callback(nioToggle, (void *)null); - groups[3] = null; - buttons[3] = enabler; + groups[4] = null; + buttons[4] = enabler; } null->end(); } diff --git a/src/UI/NioUI.h b/src/UI/NioUI.h @@ -14,7 +14,7 @@ class NioUI : public Fl_Window void refresh(); private: - const char *nullc, *alsac, *ossc, *jackc; + const char *nullc, *alsac, *ossc, *jackc, *pac; static void nioToggle(Fl_Widget *w, void *name); Fl_Group **groups;