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:
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;