From c1b10d55375dd8ecdf7b223d1f12541983422764 Mon Sep 17 00:00:00 2001 From: Miller Puckette Date: Sat, 18 Aug 2007 23:32:44 +0000 Subject: Download and adjust sources for new portaudio, portmidi. Add experimental callback scheduling. svn path=/trunk/; revision=8657 --- pd/src/CHANGELOG.txt | 4 + pd/src/configure.in | 131 ++++++++++++------------ pd/src/m_pd.h | 2 +- pd/src/m_sched.c | 80 ++++++++++++--- pd/src/makefile.dependencies | 0 pd/src/makefile.nt | 85 ++++++++-------- pd/src/s_audio.c | 237 +++++++++++++++++++------------------------ pd/src/s_audio_mmio.c | 4 +- pd/src/s_audio_pa.c | 157 ++++++++++++++++++++++++---- pd/src/s_audio_pablio.c | 55 ---------- pd/src/s_file.c | 16 ++- pd/src/s_inter.c | 4 + pd/src/s_main.c | 25 +++-- pd/src/s_midi_pm.c | 1 - pd/src/s_stuff.h | 20 ++-- pd/src/t_tkcmd.c | 12 +-- pd/src/u_main.tk | 23 +++-- pd/src/x_arithmetic.c | 3 - 18 files changed, 486 insertions(+), 373 deletions(-) delete mode 100644 pd/src/makefile.dependencies (limited to 'pd/src') diff --git a/pd/src/CHANGELOG.txt b/pd/src/CHANGELOG.txt index ccd8641d..6c0dc1e3 100644 --- a/pd/src/CHANGELOG.txt +++ b/pd/src/CHANGELOG.txt @@ -2,6 +2,10 @@ This file describes implementation and API changes; stuff more visible to the user appears in the "release notes" instead. See the bottom of this file for original notes on source stype and organization. +0.41.0 + +add support for callback-based audio I/O; changes in + 0.40.0 0.39.0 diff --git a/pd/src/configure.in b/pd/src/configure.in index 6ea60a50..e328f6aa 100644 --- a/pd/src/configure.in +++ b/pd/src/configure.in @@ -40,7 +40,7 @@ AC_ARG_ENABLE(static, [ --enable-static link statically], static=$enableval) AC_ARG_ENABLE(setuid, [ --enable-setuid install as setuid (linux)], setuid=$enableval) -AC_ARG_ENABLE(fftw, [ --enable-fftw use FFTW package], +AC_ARG_ENABLE(fftw, [ --enable-fftw use FFTW package], fftw=$enableval) dnl Checks for programs. @@ -185,9 +185,6 @@ dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. EXT=pd_linux CPPFLAGS="-DDL_OPEN -DPA_USE_OSS -DUNIX -DUNISTD\ -DUSEAPI_OSS \ - -I../portaudio/pa_common -I../portaudio/pablio \ - -I../portmidi/pm_common \ - -I../portmidi/pm_linux \ -fno-strict-aliasing" SYSSRC="s_midi_oss.c s_audio_oss.c" if test x$alsa == "xyes"; @@ -197,32 +194,41 @@ dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. LDFLAGS=$LDFLAGS" -lasound" fi - if test x$portaudio == "xyes"; - - then - CPPFLAGS=$CPPFLAGS" -DUSEAPI_PORTAUDIO -DPA19" + CPPFLAGS=$CPPFLAGS" -DUSEAPI_PORTAUDIO -DHAVE_SYS_SOUNDCARD_H \ + -Wno-error \ + -I../portaudio/include -I../portaudio/src/common \ + -I../portaudio/src/os/unix/ \ + -I../portmidi/pm_common \ + -I../portmidi/pm_linux" SYSSRC="s_audio_pa.c \ s_audio_pablio.c \ s_audio_paring.c \ - ../portaudio/pa_common/pa_allocation.c \ - ../portaudio/pa_common/pa_converters.c \ - ../portaudio/pa_common/pa_cpuload.c \ - ../portaudio/pa_common/pa_dither.c \ - ../portaudio/pa_common/pa_front.c \ - ../portaudio/pa_common/pa_process.c \ - ../portaudio/pa_common/pa_skeleton.c \ - ../portaudio/pa_common/pa_stream.c \ - ../portaudio/pa_common/pa_trace.c \ - ../portaudio/pa_unix/pa_unix_hostapis.c \ - ../portaudio/pa_unix/pa_unix_util.c \ - ../portaudio/pa_unix_oss/pa_unix_oss.c "$SYSSRC + ../portaudio/src/common/pa_allocation.c \ + ../portaudio/src/common/pa_converters.c \ + ../portaudio/src/common/pa_cpuload.c \ + ../portaudio/src/common/pa_dither.c \ + ../portaudio/src/common/pa_front.c \ + ../portaudio/src/common/pa_process.c \ + ../portaudio/src/common/pa_skeleton.c \ + ../portaudio/src/common/pa_stream.c \ + ../portaudio/src/common/pa_trace.c \ + ../portaudio/src/common/pa_debugprint.c \ + ../portaudio/src/common/pa_ringbuffer.c \ + ../portaudio/src/os/unix/pa_unix_hostapis.c \ + ../portaudio/src/os/unix/pa_unix_util.c \ + ../portaudio/src/hostapi/oss/pa_unix_oss.c "$SYSSRC if test x$alsa == "xyes"; then - SYSSRC=$SYSSRC" ../portaudio/pa_linux_alsa/pa_linux_alsa.c" - CPPFLAGS=$CPPFLAGS" -Wno-error" - fi + SYSSRC="../portaudio/src/hostapi/alsa/pa_linux_alsa.c "$SYSSRC + CPPFLAGS=$CPPFLAGS" -DPA_USE_ALSA" + fi + if test x$jack == "xyes"; + then + SYSSRC="../portaudio/src/hostapi/jack/pa_jack.c "$SYSSRC + CPPFLAGS=$CPPFLAGS" -DPA_USE_JACK" + fi fi if test x$setuid == "xyes"; then @@ -257,10 +263,11 @@ then -framework Carbon -framework CoreMIDI" EXT=pd_darwin CPPFLAGS="-DDL_OPEN -DMACOSX -DUNISTD -I/usr/X11R6/include \ - -I../portaudio/pa_common -I../portaudio/pablio \ + -I../portaudio/include -I../portaudio/src/common \ + -I../portaudio/src/os/mac_osx/ \ -I../portmidi/pm_common -I../portmidi/pm_mac \ -I../portmidi/porttime \ - -DUSEAPI_PORTAUDIO -DPA19 -DPA_USE_COREAUDIO" + -DUSEAPI_PORTAUDIO -DPA19 -DPA_USE_COREAUDIO -DNEWBUFFER" if test `uname -r` = 7.9.0; then MORECFLAGS="-DMACOSX3 -DPA_BIG_ENDIAN -Wno-error" @@ -274,18 +281,22 @@ then SYSSRC="s_midi_pm.c s_audio_pa.c \ s_audio_pablio.c \ s_audio_paring.c \ - ../portaudio/pa_common/pa_allocation.c \ - ../portaudio/pa_common/pa_converters.c \ - ../portaudio/pa_common/pa_cpuload.c \ - ../portaudio/pa_common/pa_dither.c \ - ../portaudio/pa_common/pa_front.c \ - ../portaudio/pa_common/pa_process.c \ - ../portaudio/pa_common/pa_skeleton.c \ - ../portaudio/pa_common/pa_stream.c \ - ../portaudio/pa_common/pa_trace.c \ - ../portaudio/pa_unix/pa_unix_util.c \ - ../portaudio/pa_mac_core/pa_mac_core.c \ - ../portaudio/pa_mac/pa_mac_hostapis.c \ + ../portaudio/src/common/pa_allocation.c \ + ../portaudio/src/common/pa_converters.c \ + ../portaudio/src/common/pa_cpuload.c \ + ../portaudio/src/common/pa_dither.c \ + ../portaudio/src/common/pa_front.c \ + ../portaudio/src/common/pa_process.c \ + ../portaudio/src/common/pa_skeleton.c \ + ../portaudio/src/common/pa_stream.c \ + ../portaudio/src/common/pa_trace.c \ + ../portaudio/src/common/pa_debugprint.c \ + ../portaudio/src/common/pa_ringbuffer.c \ + ../portaudio/src/os/unix/pa_unix_util.c \ + ../portaudio/src/os/mac_osx/pa_mac_hostapis.c \ + ../portaudio/src/hostapi/coreaudio/pa_mac_core.c \ + ../portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c \ + ../portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c \ ../portmidi/pm_mac/pmmac.c \ ../portmidi/pm_mac/pmmacosxcm.c \ ../portmidi/pm_common/pmutil.c \ @@ -335,26 +346,30 @@ if test `uname -s` == MINGW32_NT-5.0; then EXT=dll MORECFLAGS="-DUSEAPI_PORTAUDIO -DPA19 -DMSW -DPA_NO_DS -DPD_INTERNAL \ - -I../portaudio/pa_common -I../portaudio/pablio \ + -I../portaudio/include -I../portaudio/src/common \ + -I../portaudio/src/os/win/ \ -mwindows -mms-bitfields "$MORECFLAGS PDLIB=$PDLIB" -lwsock32 -lwinmm -lole32 -lstdc++" SYSSRC="s_audio_pa.c s_audio_pablio.c s_audio_paring.c \ s_audio_mmio.c s_midi_mmio.c \ - ../portaudio/pa_common/pa_allocation.c \ - ../portaudio/pa_common/pa_converters.c \ - ../portaudio/pa_common/pa_cpuload.c \ - ../portaudio/pa_common/pa_dither.c \ - ../portaudio/pa_common/pa_front.c \ - ../portaudio/pa_common/pa_process.c \ - ../portaudio/pa_common/pa_skeleton.c \ - ../portaudio/pa_common/pa_stream.c \ - ../portaudio/pa_common/pa_trace.c \ - ../portaudio/pa_win/pa_win_util.c \ - ../portaudio/pa_win/pa_win_hostapis.c \ - ../portaudio/pa_win_wmme/pa_win_wmme.c" - ASIOSRC="../portaudio/pa_asio/iasiothiscallresolver.cpp \ - ../portaudio/pa_asio/pa_asio.cpp ../asio/asio.cpp \ + ../portaudio/src/common/pa_allocation.c \ + ../portaudio/src/common/pa_converters.c \ + ../portaudio/src/common/pa_cpuload.c \ + ../portaudio/src/common/pa_dither.c \ + ../portaudio/src/common/pa_front.c \ + ../portaudio/src/common/pa_process.c \ + ../portaudio/src/common/pa_skeleton.c \ + ../portaudio/src/common/pa_stream.c \ + ../portaudio/src/common/pa_trace.c \ + ../portaudio/src/common/pa_debugprint.c \ + ../portaudio/src/common/pa_ringbuffer.c \ + ../portaudio/src/os/win/pa_win_util.c \ + ../portaudio/src/os/win/pa_win_hostapis.c \ + ../portaudio/src/os/win/pa_x86_plain_converters.c \ + ../portaudio/src/hostapi/wmme/pa_win_wmme.c" + ASIOSRC="../portaudio/src/hostapi/asio/iasiothiscallresolver.cpp \ + ../portaudio/src/hostapi/pa_asio/asio.cpp ../asio/asio.cpp \ ../asio/asiodrivers.cpp ../asio/asiolist.cpp" STRIPFLAG="--strip-unneeded" GUINAME="pdtcl.dll" @@ -382,18 +397,6 @@ else SYSSRC=$SYSSRC" d_fft_mayer.c d_fftroutine.c" fi -# extra flags for alpha machines -if test `uname -m | awk '{print $1}'` = alpha; -then - MORECFLAGS=$MORECFLAGS" -mieee -mcpu=ev56" -fi - -# test for compaq compiler---not sure what this does or how to test it. -if test x$CC == xccc; -then - MORECFLAGS=$MORECFLAGS" -g3 -D__COMPAQC__ -arch host" -fi - ## JMZ{ ## this does not do very much, but i guess it is a good idea to use it... AC_SYS_LARGEFILE diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h index 0b0ec5fa..5460c517 100644 --- a/pd/src/m_pd.h +++ b/pd/src/m_pd.h @@ -11,7 +11,7 @@ extern "C" { #define PD_MAJOR_VERSION 0 #define PD_MINOR_VERSION 41 #define PD_BUGFIX_VERSION 0 -#define PD_TEST_VERSION "test05" +#define PD_TEST_VERSION "test06" /* old name for "MSW" flag -- we have to take it for the sake of many old "nmakefiles" for externs, which will define NT and not MSW */ diff --git a/pd/src/m_sched.c b/pd/src/m_sched.c index bce50cd5..b21e6e79 100644 --- a/pd/src/m_sched.c +++ b/pd/src/m_sched.c @@ -7,6 +7,9 @@ #include "m_pd.h" #include "m_imp.h" #include "s_stuff.h" +#ifdef MSW +#include +#endif /* LATER consider making this variable. It's now the LCM of all sample rates we expect to see: 32000, 44100, 48000, 88200, 96000. */ @@ -15,7 +18,8 @@ #define THREAD_LOCKING #include "pthread.h" - +#define SYS_QUIT_QUIT 1 +#define SYS_QUIT_RESTART 2 static int sys_quit; double sys_time; static double sys_time_per_msec = TIMEUNITPERSEC / 1000.; @@ -326,18 +330,23 @@ void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv) void dsp_tick(void); -static int sched_usedacs = 1; +static int sched_useaudio = SCHED_AUDIO_POLL; static double sched_referencerealtime, sched_referencelogicaltime; double sys_time_per_dsp_tick; -void sched_set_using_dacs(int flag) +void sched_set_using_audio(int flag) { - sched_usedacs = flag; - if (!flag) + sched_useaudio = flag; + if (flag == SCHED_AUDIO_NONE) { sched_referencerealtime = sys_getrealtime(); sched_referencelogicaltime = clock_getlogicaltime(); } + if (flag == SCHED_AUDIO_CALLBACK && sched_useaudio != SCHED_AUDIO_CALLBACK) + sys_quit = SYS_QUIT_RESTART; + if (flag != SCHED_AUDIO_CALLBACK && sched_useaudio == SCHED_AUDIO_CALLBACK) + post("sorry, can't turn off callbacks yet; restart Pd"); /* not right yet! */ + sys_time_per_dsp_tick = (TIMEUNITPERSEC) * ((double)sys_schedblocksize) / sys_dacsr; } @@ -385,7 +394,7 @@ nonzero if you actually used the time; otherwise we're really really idle and will now sleep. */ int (*sys_idlehook)(void); -int m_scheduler( void) +static void m_pollingscheduler( void) { int idlecount = 0; sys_time_per_dsp_tick = (TIMEUNITPERSEC) * @@ -410,7 +419,7 @@ int m_scheduler( void) sys_addhist(0); waitfortick: - if (sched_usedacs) + if (sched_useaudio != SCHED_AUDIO_NONE) { #ifdef THREAD_LOCKING /* T.Grill - send_dacs may sleep -> @@ -433,6 +442,11 @@ int m_scheduler( void) if (!(idlecount & 31)) { static double idletime; + if (sched_useaudio != SCHED_AUDIO_POLL) + { + bug("m_pollingscheduler\n"); + return; + } /* on 32nd idle, start a clock watch; every 32 ensuing idles, check it */ if (idlecount == 32) @@ -441,7 +455,7 @@ int m_scheduler( void) { post("audio I/O stuck... closing audio\n"); sys_close_audio(); - sched_set_using_dacs(0); + sched_set_using_audio(SCHED_AUDIO_NONE); goto waitfortick; } } @@ -475,7 +489,6 @@ int m_scheduler( void) { sched_pollformeters(); sys_reportidle(); - #ifdef THREAD_LOCKING sys_unlock(); /* unlock while we idle */ #endif @@ -489,20 +502,61 @@ int m_scheduler( void) #ifdef THREAD_LOCKING sys_lock(); #endif - sys_addhist(5); sched_didnothing++; - } } #ifdef THREAD_LOCKING sys_unlock(); #endif +} - return (0); +void sched_audio_callbackfn(void) +{ + sys_setmiditimediff(0, 1e-6 * sys_schedadvance); + sys_addhist(1); + sched_tick(sys_time + sys_time_per_dsp_tick); + sys_addhist(2); + sys_pollmidiqueue(); + sys_addhist(3); + sys_pollgui(); + sys_addhist(5); + sched_pollformeters(); + sys_addhist(0); +} + +static void m_callbackscheduler(void) +{ + sys_initmidiqueue(); + while (1) + { +#ifdef MSW + Sleep(1000); +#else + sleep(1); +#endif + if (sys_idlehook) + sys_idlehook(); + } } +int m_mainloop(void) +{ + while (sys_quit != SYS_QUIT_QUIT) + { + if (sched_useaudio == SCHED_AUDIO_CALLBACK) + m_callbackscheduler(); + else m_pollingscheduler(); + if (sys_quit == SYS_QUIT_RESTART) + { + sys_quit = 0; + sys_close_audio(); + sys_reopen_audio(); + } + } + return (0); +} /* ------------ thread locking ------------------- */ @@ -534,5 +588,5 @@ int sys_trylock(void) {} void sys_exit(void) { - sys_quit = 1; + sys_quit = SYS_QUIT_QUIT; } diff --git a/pd/src/makefile.dependencies b/pd/src/makefile.dependencies deleted file mode 100644 index e69de29b..00000000 diff --git a/pd/src/makefile.nt b/pd/src/makefile.nt index fc624896..d60651cd 100644 --- a/pd/src/makefile.nt +++ b/pd/src/makefile.nt @@ -38,19 +38,20 @@ SRC = g_canvas.c g_graph.c g_text.c g_rtext.c g_array.c g_template.c g_io.c \ $(SYSSRC) PADIR = ..\portaudio -INCPA = -I$(PADIR) -I$(PADIR)\pa_common -I$(PADIR)\pablio -I..\lib\asio -SRCPA = $(PADIR)/pa_common/pa_stream.c \ - $(PADIR)/pa_common/pa_trace.c \ - $(PADIR)/pa_common/pa_skeleton.c \ - $(PADIR)/pa_common/pa_process.c \ - $(PADIR)/pa_common/pa_front.c \ - $(PADIR)/pa_common/pa_dither.c \ - $(PADIR)/pa_common/pa_cpuload.c \ - $(PADIR)/pa_common/pa_converters.c \ - $(PADIR)/pa_common/pa_allocation.c \ - $(PADIR)/pa_win/pa_win_util.c \ - $(PADIR)/pa_win/pa_win_hostapis.c \ - $(PADIR)/pa_win_wmme/pa_win_wmme.c +INCPA = -I$(PADIR)\include -I$(PADIR)\src\common -I..\lib\asio +PASRC = $(PADIR)\src +SRCPA = $(PASRC)/common/pa_stream.c \ + $(PASRC)/common/pa_trace.c \ + $(PASRC)/common/pa_skeleton.c \ + $(PASRC)/common/pa_process.c \ + $(PASRC)/common/pa_front.c \ + $(PASRC)/common/pa_dither.c \ + $(PASRC)/common/pa_cpuload.c \ + $(PASRC)/common/pa_converters.c \ + $(PASRC)/common/pa_allocation.c \ + $(PASRC)/os/win/pa_win_hostapis.c \ + $(PASRC)/os/win/pa_win_util.c \ + $(PASRC)/hostapi/wmme/pa_win_wmme.c # $(PADIR)/pa_win_wdmks/pa_win_wdmks.c SRCASIO = $(PADIR)/pa_asio/pa_asio.cpp @@ -63,12 +64,12 @@ $(LDIR)\odbc32.lib $(LDIR)\odbccp32.lib ..\lib\asio\asiolib.lib PAOBJ = pa_stream.obj pa_trace.obj pa_skeleton.obj pa_process.obj \ pa_front.obj pa_dither.obj pa_cpuload.obj pa_converters.obj \ - pa_allocation.obj pa_win_util.obj pa_win_hostapis.obj pa_asio.obj \ + pa_allocation.obj pa_win_hostapis.obj pa_win_util.obj pa_asio.obj \ pa_win_wmme.obj # pa_win_wdmks.obj PMDIR = ..\portmidi -INCPM = -I$(PMDIR)\pm_common -I$(PMDIR)\pm_win -I$(PMDIR)\porttime +INCPM = -I$(PMDIR)\pm_common -I$(PMDIR)\pm_win -I$(PMDIR)\porttime -DNEWBUFFER SRCPM = $(PADIR)/pm_common/portmidi.c \ $(PMDIR)/pm_common/pmutil.c \ $(PMDIR)/porttime/porttime.c \ @@ -127,37 +128,37 @@ s_entry_com.obj: s_entry.c ..\bin\pd.lib $(LIB) $(ASIOLIB) # explicit rules to compile portaudio sources: -pa_stream.obj: $(PADIR)\pa_common\pa_stream.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_stream.c -pa_trace.obj: $(PADIR)\pa_common\pa_trace.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_trace.c -pa_skeleton.obj: $(PADIR)\pa_common\pa_skeleton.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_skeleton.c -pa_process.obj: $(PADIR)\pa_common\pa_process.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_process.c -pa_front.obj: $(PADIR)\pa_common\pa_front.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_front.c -pa_dither.obj: $(PADIR)\pa_common\pa_dither.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_dither.c -pa_cpuload.obj: $(PADIR)\pa_common\pa_cpuload.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_cpuload.c -pa_converters.obj: $(PADIR)\pa_common\pa_converters.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_converters.c -pa_allocation.obj: $(PADIR)\pa_common\pa_allocation.c - cl /c $(ALLCF) $(PADIR)\pa_common\pa_allocation.c - -pa_win_util.obj: $(PADIR)\pa_win\pa_win_util.c - cl /c $(ALLCF) $(PADIR)\pa_win\pa_win_util.c -pa_win_hostapis.obj: $(PADIR)\pa_win\pa_win_hostapis.c - cl /c $(ALLCF) $(PADIR)\pa_win\pa_win_hostapis.c -pa_win_wmme.obj: $(PADIR)\pa_win_wmme\pa_win_wmme.c - cl /c $(ALLCF) $(PADIR)\pa_win_wmme\pa_win_wmme.c +pa_stream.obj: $(PASRC)\common\pa_stream.c + cl /c $(ALLCF) $(PASRC)\common\pa_stream.c +pa_trace.obj: $(PASRC)\common\pa_trace.c + cl /c $(ALLCF) $(PASRC)\common\pa_trace.c +pa_skeleton.obj: $(PASRC)\common\pa_skeleton.c + cl /c $(ALLCF) $(PASRC)\common\pa_skeleton.c +pa_process.obj: $(PASRC)\common\pa_process.c + cl /c $(ALLCF) $(PASRC)\common\pa_process.c +pa_front.obj: $(PASRC)\common\pa_front.c + cl /c $(ALLCF) $(PASRC)\common\pa_front.c +pa_dither.obj: $(PASRC)\common\pa_dither.c + cl /c $(ALLCF) $(PASRC)\common\pa_dither.c +pa_cpuload.obj: $(PASRC)\common\pa_cpuload.c + cl /c $(ALLCF) $(PASRC)\common\pa_cpuload.c +pa_converters.obj: $(PASRC)\common\pa_converters.c + cl /c $(ALLCF) $(PASRC)\common\pa_converters.c +pa_allocation.obj: $(PASRC)\common\pa_allocation.c + cl /c $(ALLCF) $(PASRC)\common\pa_allocation.c + +pa_win_hostapis.obj: $(PASRC)\os\win\pa_win_hostapis.c + cl /c $(ALLCF) $(PASRC)\os\win\pa_win_hostapis.c +pa_win_util.obj: $(PASRC)\os\win\pa_win_util.c + cl /c $(ALLCF) $(PASRC)\os\win\pa_win_util.c +pa_win_wmme.obj: $(PASRC)\hostapi\wmme\pa_win_wmme.c + cl /c $(ALLCF) $(PASRC)\hostapi\wmme\pa_win_wmme.c pa_win_wdmks.obj: $(PADIR)\pa_win_wdmks\pa_win_wdmks.c cl /c $(ALLCF) \ -DWINVER=0x400 -DKSAUDIO_SPEAKER_DIRECTOUT \ $(PADIR)\pa_win_wdmks\pa_win_wdmks.c -pa_asio.obj: $(PADIR)\pa_asio\pa_asio.cpp - cl /c $(ALLCF) $(PADIR)\pa_asio\pa_asio.cpp +pa_asio.obj: $(PASRC)\hostapi\asio\pa_asio.cpp + cl /c $(ALLCF) $(PASRC)\hostapi\asio\pa_asio.cpp portmidi.obj: $(PMDIR)\pm_common\portmidi.c cl /c $(ALLCF) $(PMDIR)\pm_common\portmidi.c diff --git a/pd/src/s_audio.c b/pd/src/s_audio.c index f33a135b..a211ae98 100644 --- a/pd/src/s_audio.c +++ b/pd/src/s_audio.c @@ -29,7 +29,7 @@ typedef long t_pa_sample; #define DEVDESCSIZE 80 static void audio_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, + char *outdevlist, int *noutdevs, int *canmulti, int *cancallback, int maxndev, int devdescsize); /* these are set in this file when opening audio, but then may be reduced, @@ -65,6 +65,9 @@ static int audio_audiooutdev[MAXAUDIOOUTDEV]; static int audio_audiochoutdev[MAXAUDIOOUTDEV]; static int audio_rate; static int audio_advance; +static int audio_callback; + +void sched_audio_callbackfn(void); static int audio_isopen(void) { @@ -76,7 +79,7 @@ static int audio_isopen(void) void sys_get_audio_params( int *pnaudioindev, int *paudioindev, int *chindev, int *pnaudiooutdev, int *paudiooutdev, int *choutdev, - int *prate, int *padvance) + int *prate, int *padvance, int *pcallback) { int i; *pnaudioindev = audio_naudioindev; @@ -89,12 +92,13 @@ void sys_get_audio_params( choutdev[i] = audio_audiochoutdev[i]; *prate = audio_rate; *padvance = audio_advance; + *pcallback = audio_callback; } void sys_save_audio_params( int naudioindev, int *audioindev, int *chindev, int naudiooutdev, int *audiooutdev, int *choutdev, - int rate, int advance) + int rate, int advance, int callback) { int i; audio_naudioindev = naudioindev; @@ -107,6 +111,7 @@ void sys_save_audio_params( audio_audiochoutdev[i] = choutdev[i]; audio_rate = rate; audio_advance = advance; + audio_callback = callback; } /* init routines for any API which needs to set stuff up before @@ -165,14 +170,14 @@ void sys_setchsr(int chin, int chout, int sr) /* ----------------------- public routines ----------------------- */ - /* open audio devices (after cleaning up the specified device and channel - vectors). The audio devices are "zero based" (i.e. "0" means the first - one.) We also save the cleaned-up device specification so that we - can later re-open audio and/or show the settings on a dialog window. */ + /* set audio device settings (after cleaning up the specified device and + channel vectors). The audio devices are "zero based" (i.e. "0" means the + first one.) We can later re-open audio and/or show the settings on a\ + dialog window. */ -void sys_open_audio(int naudioindev, int *audioindev, int nchindev, +void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate, int advance, int enable) + int *choutdev, int rate, int advance, int callback) { int i, *ip; int defaultchannels = SYS_DEFAULTCH; @@ -181,10 +186,9 @@ void sys_open_audio(int naudioindev, int *audioindev, int nchindev, int realinchans[MAXAUDIOINDEV], realoutchans[MAXAUDIOOUTDEV]; char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int indevs = 0, outdevs = 0, canmulti = 0; + int indevs = 0, outdevs = 0, canmulti = 0, cancallback = 0; audio_getdevs(indevlist, &indevs, outdevlist, &outdevs, &canmulti, - MAXNDEV, DEVDESCSIZE); - + &cancallback, MAXNDEV, DEVDESCSIZE); if (sys_externalschedlib) { return; @@ -319,73 +323,11 @@ void sys_open_audio(int naudioindev, int *audioindev, int nchindev, outchans += choutdev[i]; nrealoutdev++; } - /* if no input or output devices seem to have been specified, - this really means just disable audio, which we now do. */ - if (!inchans && !outchans) - enable = 0; sys_schedadvance = advance * 1000; sys_setchsr(inchans, outchans, rate); sys_log_error(ERR_NOTHING); - if (enable) - { -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) - { - int blksize = (sys_blocksize ? sys_blocksize : 64); - pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout, - blksize, sys_advance_samples/blksize, - (naudiooutdev > 0 ? audioindev[0] : 0), - (naudiooutdev > 0 ? audiooutdev[0] : 0)); - } -else -#endif -#ifdef USEAPI_JACK - if (sys_audioapi == API_JACK) - jack_open_audio((nrealindev > 0 ? realinchans[0] : 0), - (nrealoutdev > 0 ? realoutchans[0] : 0), rate); - - else -#endif -#ifdef USEAPI_OSS - if (sys_audioapi == API_OSS) - oss_open_audio(nrealindev, realindev, nrealindev, realinchans, - nrealoutdev, realoutdev, nrealoutdev, realoutchans, rate); - else -#endif -#ifdef USEAPI_ALSA - /* for alsa, only one device is supported; it may - be open for both input and output. */ - if (sys_audioapi == API_ALSA) - alsa_open_audio(nrealindev, audioindev, nrealindev, realinchans, - nrealoutdev, audiooutdev, nrealoutdev, realoutchans, rate); - else -#endif -#ifdef USEAPI_SGI - if (sys_audioapi == API_SGI) - { - xtern int sgi_open_audio(int nindev, int *indev, int nchin, - int *chin, int noutdev, int *outdev, int nchout, int *chout, - int rate); - sgi_open_audio(naudioindev, audioindev, nchindev, chindev, - naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); - } - else -#endif -#ifdef USEAPI_MMIO - if (sys_audioapi == API_MMIO) - mmio_open_audio(nrealindev, audioindev, nrealindev, realinchans, - nrealoutdev, audiooutdev, nrealoutdev, realoutchans, rate); - else -#endif - post("unknown audio API specified"); - } - sys_save_audio_params(naudioindev, audioindev, chindev, - naudiooutdev, audiooutdev, choutdev, sys_dacsr, advance); - if (sys_inchannels == 0 && sys_outchannels == 0) - enable = 0; - audio_state = enable; - sys_vgui("set pd_whichapi %d\n", (audio_isopen() ? sys_audioapi : 0)); - sched_set_using_dacs(enable); + sys_save_audio_params(nrealindev, realindev, realinchans, + nrealoutdev, realoutdev, realoutchans, sys_dacsr, advance, callback); } void sys_close_audio(void) @@ -416,14 +358,6 @@ void sys_close_audio(void) alsa_close_audio(); else #endif -#ifdef USEAPI_SGI - if (sys_audioapi == API_SGI) - { - extern void sgi_close_audio(void); - sgi_close_audio(); - } - else -#endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) mmio_close_audio(); @@ -431,6 +365,7 @@ void sys_close_audio(void) #endif post("sys_close_audio: unknown API %d", sys_audioapi); sys_inchannels = sys_outchannels = 0; + sched_set_using_audio(SCHED_AUDIO_NONE); } /* open audio using whatever parameters were last used */ @@ -438,11 +373,67 @@ void sys_reopen_audio( void) { int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; - int rate, advance; + int rate, advance, callback, outcome = 0; sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance); - sys_open_audio(naudioindev, audioindev, naudioindev, chindev, - naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, 1); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); + if (!naudioindev && !naudiooutdev) + { + sched_set_using_audio(SCHED_AUDIO_NONE); + return; + } +#ifdef USEAPI_PORTAUDIO + if (sys_audioapi == API_PORTAUDIO) + { + int blksize = (sys_blocksize ? sys_blocksize : 64); + outcome = pa_open_audio((naudioindev > 0 ? chindev[0] : 0), + (naudiooutdev > 0 ? choutdev[0] : 0), rate, sys_soundin, + sys_soundout, blksize, sys_advance_samples/blksize, + (naudioindev > 0 ? audioindev[0] : 0), + (naudiooutdev > 0 ? audiooutdev[0] : 0), + (callback ? sched_audio_callbackfn : 0)); + } + else +#endif +#ifdef USEAPI_JACK + if (sys_audioapi == API_JACK) + outcome = jack_open_audio((naudioindev > 0 ? chindev[0] : 0), + (naudioindev > 0 ? choutdev[0] : 0), rate); + + else +#endif +#ifdef USEAPI_OSS + if (sys_audioapi == API_OSS) + outcome = oss_open_audio(naudioindev, audioindev, naudioindev, + chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); + else +#endif +#ifdef USEAPI_ALSA + /* for alsa, only one device is supported; it may + be open for both input and output. */ + if (sys_audioapi == API_ALSA) + outcome = alsa_open_audio(naudioindev, audioindev, naudioindev, + chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); + else +#endif +#ifdef USEAPI_MMIO + if (sys_audioapi == API_MMIO) + outcome = mmio_open_audio(naudioindev, audioindev, naudioindev, + chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); + else +#endif + post("unknown audio API specified"); + if (outcome) /* failed */ + { + audio_state = 0; + sched_set_using_audio(SCHED_AUDIO_NONE); + } + else + { + audio_state = 1; + sched_set_using_audio( + (callback ? SCHED_AUDIO_CALLBACK : SCHED_AUDIO_POLL)); + } + sys_vgui("set pd_whichapi %d\n", (outcome == 0 ? sys_audioapi : 0)); } int sys_send_dacs(void) @@ -489,14 +480,6 @@ int sys_send_dacs(void) return (alsa_send_dacs()); else #endif -#ifdef USEAPI_SGI - if (sys_audioapi == API_SGI) - { - extern int sgi_send_dacs(void); - return (sgi_send_dacs()); - } - else -#endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) return (mmio_send_dacs()); @@ -539,15 +522,17 @@ void sys_reportidle(void) } static void audio_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, + char *outdevlist, int *noutdevs, int *canmulti, int *cancallback, int maxndev, int devdescsize) { audio_init(); + *cancallback = 0; /* may be overridden by specific API implementation */ #ifdef USEAPI_PORTAUDIO if (sys_audioapi == API_PORTAUDIO) { pa_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, maxndev, devdescsize); + *cancallback = 1; } else #endif @@ -575,17 +560,6 @@ static void audio_getdevs(char *indevlist, int *nindevs, } else #endif -#ifdef USEAPI_SGI - if (sys_audioapi == API_SGI) - { - extern void sgi_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, - int maxndev, int devdescsize); - sgi_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, - maxndev, devdescsize); - } - else -#endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) { @@ -611,10 +585,10 @@ static void audio_getdevs(char *indevlist, int *nindevs, static void sys_listaudiodevs(void ) { char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0, i, canmulti = 0; + int nindevs = 0, noutdevs = 0, i, canmulti = 0, cancallback = 0; audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti, - MAXNDEV, DEVDESCSIZE); + &cancallback, MAXNDEV, DEVDESCSIZE); if (!nindevs) post("no audio input devices found"); @@ -653,13 +627,13 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform) audioinchan1, audioinchan2, audioinchan3, audioinchan4, audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4, audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4; - int rate, advance; + int rate, advance, callback; /* these are all the devices on your system: */ char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0, canmulti = 0, i; + int nindevs = 0, noutdevs = 0, canmulti = 0, cancallback = 0, i; audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti, - MAXNDEV, DEVDESCSIZE); + &cancallback, MAXNDEV, DEVDESCSIZE); sys_gui("global audio_indevlist; set audio_indevlist {}\n"); for (i = 0; i < nindevs; i++) @@ -672,7 +646,7 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform) outdevlist + i * DEVDESCSIZE); sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); /* post("naudioindev %d naudiooutdev %d longform %f", naudioindev, naudiooutdev, flongform); */ @@ -699,12 +673,13 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform) "pdtk_audio_dialog %%s \ %d %d %d %d %d %d %d %d \ %d %d %d %d %d %d %d %d \ -%d %d %d %d\n", +%d %d %d %d %d\n", audioindev1, audioindev2, audioindev3, audioindev4, audioinchan1, audioinchan2, audioinchan3, audioinchan4, audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4, audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4, - rate, advance, canmulti, (flongform != 0)); + rate, advance, canmulti, (cancallback ? callback : -1), + (flongform != 0)); gfxstub_deleteforkey(0); gfxstub_new(&glob_pdobject, (void *)glob_audio_properties, buf); } @@ -721,6 +696,7 @@ void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) /* the new values the dialog came back with: */ int newrate = atom_getintarg(16, argc, argv); int newadvance = atom_getintarg(17, argc, argv); + int newcallback = atom_getintarg(18, argc, argv); int statewas; for (i = 0; i < 4; i++) @@ -753,11 +729,18 @@ void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) noutdev++; } } - - sys_close_audio(); - sys_open_audio(nindev, newaudioindev, nindev, newaudioinchan, + + if (newcallback < 0) + newcallback = 0; + post("callback %d new %d",audio_callback, newcallback) ; + if (audio_callback == newcallback) + sys_close_audio(); + sys_set_audio_settings(nindev, newaudioindev, nindev, newaudioinchan, noutdev, newaudiooutdev, noutdev, newaudiooutchan, - newrate, newadvance, 1); + newrate, newadvance, (newcallback >= 0 ? newcallback : 0)); + post("callback %d new %d",audio_callback, newcallback) ; + if (audio_callback == newcallback) + sys_reopen_audio(); } void sys_listdevs(void ) @@ -782,12 +765,6 @@ void sys_listdevs(void ) sys_listaudiodevs(); else #endif -#ifdef USEAPI_SGI - extern void sgi_listaudiodevs(void); - if (sys_audioapi == API_SGI) - sgi_listaudiodevs(); - else -#endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) sys_listaudiodevs(); @@ -841,7 +818,6 @@ void glob_audio_setapi(void *dummy, t_floatarg f) { sys_close_audio(); audio_state = 0; - sched_set_using_dacs(0); } } @@ -856,10 +832,7 @@ void sys_set_audio_state(int onoff) else { if (audio_isopen()) - { sys_close_audio(); - sched_set_using_dacs(0); - } } audio_state = onoff; } @@ -888,9 +861,6 @@ void sys_get_audio_apis(char *buf) #else sprintf(buf + strlen(buf), "{portaudio %d} ", API_PORTAUDIO); #endif -#ifdef USEAPI_SGI - sprintf(buf + strlen(buf), "{SGI %d} ", API_SGI); n++; -#endif #endif n++; #endif @@ -901,7 +871,6 @@ void sys_get_audio_apis(char *buf) /* then again, if only one API (or none) we don't offer any choice. */ if (n < 2) strcpy(buf, "{}"); - } #ifdef USEAPI_ALSA diff --git a/pd/src/s_audio_mmio.c b/pd/src/s_audio_mmio.c index a949767a..cf79f135 100644 --- a/pd/src/s_audio_mmio.c +++ b/pd/src/s_audio_mmio.c @@ -694,7 +694,7 @@ idle: /* ------------------- public routines -------------------------- */ -void mmio_open_audio(int naudioindev, int *audioindev, +int mmio_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate) { @@ -724,7 +724,7 @@ void mmio_open_audio(int naudioindev, int *audioindev, (nt_nwaveout > 1 ? WAVE_MAPPER : -1) : audiooutdev[0]); if (naudiooutdev > 1 || naudioindev > 1) post("separate audio device choice not supported; using sequential devices."); - mmio_do_open_audio(); + return (mmio_do_open_audio()); } diff --git a/pd/src/s_audio_pa.c b/pd/src/s_audio_pa.c index 627b0015..f05c41d8 100644 --- a/pd/src/s_audio_pa.c +++ b/pd/src/s_audio_pa.c @@ -23,22 +23,138 @@ static PABLIO_Stream *pa_stream; static int pa_inchans, pa_outchans; static float *pa_soundin, *pa_soundout; +static t_audiocallback pa_callback; #define MAX_PA_CHANS 32 #define MAX_SAMPLES_PER_FRAME MAX_PA_CHANS * DEFDACBLKSIZE -#ifndef PA19 -#define Pa_GetDeviceCount Pa_CountDevices -#endif +static int pa_lowlevel_callback(const void *inputBuffer, + void *outputBuffer, unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags myflags, + void *userData) +{ + int i; + unsigned int j; + float *fbuf, *fp2, *fp3, *soundiop; + if (framesPerBuffer != DEFDACBLKSIZE) + { + fprintf(stderr, "ignoring buffer size %d\n", framesPerBuffer); + return; + } + if (inputBuffer != NULL) + { + fbuf = (float *)inputBuffer; + soundiop = pa_soundin; + for (i = 0, fp2 = fbuf; i < pa_inchans; i++, fp2++) + for (j = 0, fp3 = fp2; j < framesPerBuffer; j++, fp3 += pa_inchans) + *soundiop++ = *fp3; + } + else memset((void *)pa_soundin, 0, + framesPerBuffer * pa_inchans * sizeof(float)); + (*pa_callback)(); + if (outputBuffer != NULL) + { + fbuf = (float *)outputBuffer; + soundiop = pa_soundout; + for (i = 0, fp2 = fbuf; i < pa_outchans; i++, fp2++) + for (j = 0, fp3 = fp2; j < framesPerBuffer; j++, fp3 += pa_outchans) + *fp3 = *soundiop++; + } + + return 0; +} + +PaError pa_open_callback(double sampleRate, int inchannels, int outchannels, + int framesperbuf, int nbuffers, int indeviceno, int outdeviceno) +{ + long bytesPerSample; + PaError err; + PABLIO_Stream *pastream; + long numFrames; + PaStreamParameters instreamparams, outstreamparams; + + if (indeviceno < 0) + { + indeviceno = Pa_GetDefaultInputDevice(); + fprintf(stderr, "using default input device number: %d\n", indeviceno); + } + if (outdeviceno < 0) + { + outdeviceno = Pa_GetDefaultOutputDevice(); + fprintf(stderr, "using default output device number: %d\n", outdeviceno); + } + /* fprintf(stderr, "nchan %d, flags %d, bufs %d, framesperbuf %d\n", + nchannels, flags, nbuffers, framesperbuf); */ + + /* Allocate PABLIO_Stream structure for caller. */ + pastream = (PABLIO_Stream *)malloc( sizeof(PABLIO_Stream)); + if (pastream == NULL) + return (1); + memset(pastream, 0, sizeof(PABLIO_Stream)); + + /* Determine size of a sample. */ + bytesPerSample = Pa_GetSampleSize(paFloat32); + if (bytesPerSample < 0) + { + err = (PaError) bytesPerSample; + goto error; + } + pastream->insamplesPerFrame = inchannels; + pastream->inbytesPerFrame = bytesPerSample * pastream->insamplesPerFrame; + pastream->outsamplesPerFrame = outchannels; + pastream->outbytesPerFrame = bytesPerSample * pastream->outsamplesPerFrame; + + numFrames = nbuffers * framesperbuf; + + instreamparams.device = indeviceno; + instreamparams.channelCount = inchannels; + instreamparams.sampleFormat = paFloat32; + instreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; + instreamparams.hostApiSpecificStreamInfo = 0; + + outstreamparams.device = outdeviceno; + outstreamparams.channelCount = outchannels; + outstreamparams.sampleFormat = paFloat32; + outstreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; + outstreamparams.hostApiSpecificStreamInfo = 0; + + err = Pa_OpenStream( + &pastream->stream, + (inchannels ? &instreamparams : 0), + (outchannels ? &outstreamparams : 0), + sampleRate, + DEFDACBLKSIZE, + paNoFlag, /* portaudio will clip for us */ + pa_lowlevel_callback, + pastream); + if (err != paNoError) + goto error; + + err = Pa_StartStream(pastream->stream); + if (err != paNoError) + { + fprintf(stderr, "Pa_StartStream failed; closing audio stream...\n"); + CloseAudioStream( pastream ); + goto error; + } + pa_stream = pastream; + return paNoError; +error: + pa_stream = NULL; + return err; +} int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin, t_sample *soundout, int framesperbuf, int nbuffers, - int indeviceno, int outdeviceno) + int indeviceno, int outdeviceno, t_audiocallback callbackfn) { PaError err; static int initialized; int j, devno, pa_indev = 0, pa_outdev = 0; - + + pa_callback = callbackfn; + if (callbackfn) + fprintf(stderr, "callback enabled\n"); if (!initialized) { /* Initialize PortAudio */ @@ -105,26 +221,34 @@ int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin, post("output device %d, channels %d", pa_outdev, outchans); post("framesperbuf %d, nbufs %d", framesperbuf, nbuffers); } - if (inchans || outchans) + pa_inchans = inchans; + pa_outchans = outchans; + pa_soundin = soundin; + pa_soundout = soundout; + if (! inchans && !outchans) + return(0); + if (callbackfn) + { + pa_callback = callbackfn; + err = pa_open_callback(rate, inchans, outchans, + framesperbuf, nbuffers, pa_indev, pa_outdev); + } + else + { err = OpenAudioStream( &pa_stream, rate, paFloat32, inchans, outchans, framesperbuf, nbuffers, pa_indev, pa_outdev); - else err = 0; + } if ( err != paNoError ) { - fprintf( stderr, "Error number %d occured opening portaudio stream\n", + fprintf(stderr, "Error number %d opening portaudio stream\n", err); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); Pa_Terminate(); - sys_inchannels = sys_outchannels = 0; return (1); } else if (sys_verbose) post("... opened OK."); - pa_inchans = inchans; - pa_outchans = outchans; - pa_soundin = soundin; - pa_soundout = soundout; return (0); } @@ -235,17 +359,10 @@ void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */ fprintf(stderr, " %s;", pdi->name ); fprintf(stderr, "%d inputs, ", pdi->maxInputChannels ); fprintf(stderr, "%d outputs", pdi->maxOutputChannels ); -#ifdef PA19 if ( i == Pa_GetDefaultInputDevice() ) fprintf(stderr, " (Default Input)"); if ( i == Pa_GetDefaultOutputDevice() ) fprintf(stderr, " (Default Output)"); -#else - if ( i == Pa_GetDefaultInputDeviceID() ) - fprintf(stderr, " (Default Input)"); - if ( i == Pa_GetDefaultOutputDeviceID() ) - fprintf(stderr, " (Default Output)"); -#endif fprintf(stderr, "\n"); } diff --git a/pd/src/s_audio_pablio.c b/pd/src/s_audio_pablio.c index 5827533f..0873f269 100644 --- a/pd/src/s_audio_pablio.c +++ b/pd/src/s_audio_pablio.c @@ -58,17 +58,11 @@ static void NPa_Sleep(int n) /* MSP wrapper to check we never stall... */ /******** Prototypes ****************************************************/ /************************************************************************/ -#ifdef PA19 static int blockingIOCallback( const void *inputBuffer, void *outputBuffer, /*MSP */ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags myflags, void *userData ); -#else -static int blockingIOCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ); -#endif static PaError PABLIO_InitFIFO( sys_ringbuf *rbuf, long numFrames, long bytesPerFrame ); static PaError PABLIO_TermFIFO( sys_ringbuf *rbuf ); @@ -79,17 +73,11 @@ static PaError PABLIO_TermFIFO( sys_ringbuf *rbuf ); /* Called from PortAudio. * Read and write data only if there is room in FIFOs. */ -#ifdef PA19 static int blockingIOCallback( const void *inputBuffer, void *outputBuffer, /* MSP */ unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags myflags, void *userData ) -#else -static int blockingIOCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -#endif { PABLIO_Stream *data = (PABLIO_Stream*)userData; (void) outTime; @@ -223,11 +211,7 @@ PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, PaError err; PABLIO_Stream *aStream; long numFrames; -#ifdef PA19 PaStreamParameters instreamparams, outstreamparams; /* MSP */ -#else - long minNumBuffers; -#endif /* fprintf(stderr, "open %lf fmt %d flags %d ch: %d fperbuf: %d nbuf: %d devs: %d %d\n", @@ -236,20 +220,12 @@ PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, if (indeviceno < 0) /* MSP... */ { -#ifdef PA19 indeviceno = Pa_GetDefaultInputDevice(); -#else - indeviceno = Pa_GetDefaultInputDeviceID(); -#endif fprintf(stderr, "using default input device number: %d\n", indeviceno); } if (outdeviceno < 0) { -#ifdef PA19 outdeviceno = Pa_GetDefaultOutputDevice(); -#else - outdeviceno = Pa_GetDefaultOutputDeviceID(); -#endif fprintf(stderr, "using default output device number: %d\n", outdeviceno); } /* fprintf(stderr, "nchan %d, flags %d, bufs %d, framesperbuf %d\n", @@ -277,7 +253,6 @@ PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, err = Pa_Initialize(); if( err != paNoError ) goto error; -#ifdef PA19 numFrames = nbuffers * framesperbuf; /* ...MSP */ instreamparams.device = indeviceno; /* MSP... */ @@ -292,17 +267,6 @@ PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, outstreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate; outstreamparams.hostApiSpecificStreamInfo = 0; /* ... MSP */ -#else -/* Warning: numFrames must be larger than amount of data processed per - interrupt inside PA to prevent glitches. */ /* MSP */ - minNumBuffers = Pa_GetMinNumBuffers(framesperbuf, sampleRate); - if (minNumBuffers > nbuffers) - fprintf(stderr, - "warning: number of buffers %d less than recommended minimum %d\n", - (int)nbuffers, (int)minNumBuffers); -#endif - - numFrames = nbuffers * framesperbuf; /* fprintf(stderr, "numFrames %d\n", numFrames); */ /* Initialize Ring Buffers */ @@ -327,7 +291,6 @@ PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, /* Open a PortAudio stream that we will use to communicate with the underlying * audio drivers. */ -#ifdef PA19 err = Pa_OpenStream( &aStream->stream, (doRead ? &instreamparams : 0), /* MSP */ @@ -337,24 +300,6 @@ PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate, paNoFlag, /* MSP -- portaudio will clip for us */ blockingIOCallback, aStream ); -#else - err = Pa_OpenStream( - &aStream->stream, - (doRead ? indeviceno : paNoDevice), /* MSP */ - (doRead ? aStream->insamplesPerFrame : 0 ), - format, - NULL, - (doWrite ? outdeviceno : paNoDevice), /* MSP */ - (doWrite ? aStream->outsamplesPerFrame : 0 ), - format, - NULL, - sampleRate, - framesperbuf, /* MSP */ - nbuffers, /* MSP */ - paNoFlag, /* MSP -- portaudio will clip for us */ - blockingIOCallback, - aStream ); -#endif if( err != paNoError ) goto error; err = Pa_StartStream( aStream->stream ); diff --git a/pd/src/s_file.c b/pd/src/s_file.c index 53d71bfa..c81d423b 100644 --- a/pd/src/s_file.c +++ b/pd/src/s_file.c @@ -288,7 +288,7 @@ void sys_loadpreferences( void) int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; int nmidiindev, midiindev[MAXMIDIINDEV]; int nmidioutdev, midioutdev[MAXMIDIOUTDEV]; - int i, rate = 0, advance = 0, api, nolib, maxi; + int i, rate = 0, advance = 0, callback = 0, api, nolib, maxi; char prefbuf[MAXPDSTRING], keybuf[80]; sys_initloadpreferences(); @@ -337,8 +337,11 @@ void sys_loadpreferences( void) sscanf(prefbuf, "%d", &rate); if (sys_getpreference("audiobuf", prefbuf, MAXPDSTRING)) sscanf(prefbuf, "%d", &advance); - sys_open_audio(naudioindev, audioindev, naudioindev, chindev, - naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, 0); + if (sys_getpreference("callback", prefbuf, MAXPDSTRING)) + sscanf(prefbuf, "%d", &callback); + sys_set_audio_settings(naudioindev, audioindev, naudioindev, chindev, + naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, + callback); /* load MIDI preferences */ /* JMZ/MB: brackets for initializing */ @@ -423,7 +426,7 @@ void glob_savepreferences(t_pd *dummy) { int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; - int i, rate, advance; + int i, rate, advance, callback; char buf1[MAXPDSTRING], buf2[MAXPDSTRING]; int nmidiindev, midiindev[MAXMIDIINDEV]; int nmidioutdev, midioutdev[MAXMIDIOUTDEV]; @@ -436,7 +439,7 @@ void glob_savepreferences(t_pd *dummy) sys_putpreference("audioapi", buf1); sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); sys_putpreference("noaudioin", (naudioindev <= 0 ? "True" : "False")); for (i = 0; i < naudioindev; i++) @@ -459,6 +462,9 @@ void glob_savepreferences(t_pd *dummy) sprintf(buf1, "%d", rate); sys_putpreference("rate", buf1); + sprintf(buf1, "%d", callback); + sys_putpreference("callback", buf1); + /* MIDI settings */ sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev); sys_putpreference("nomidiin", (nmidiindev <= 0 ? "True" : "False")); diff --git a/pd/src/s_inter.c b/pd/src/s_inter.c index e6c69bf6..9945466f 100644 --- a/pd/src/s_inter.c +++ b/pd/src/s_inter.c @@ -1079,6 +1079,10 @@ int sys_startgui(const char *guidir) goto foundit; nohomedir: /* Perform the same search among system applications. */ + strcpy(filename, + "/usr/bin/wish"); + if (stat(filename, &statbuf) >= 0) + goto foundit; strcpy(filename, "/Applications/Utilities/Wish Shell.app/Contents/MacOS/Wish Shell"); if (stat(filename, &statbuf) >= 0) diff --git a/pd/src/s_main.c b/pd/src/s_main.c index c170aec5..ded67c88 100644 --- a/pd/src/s_main.c +++ b/pd/src/s_main.c @@ -31,7 +31,7 @@ int sys_argparse(int argc, char **argv); void sys_findprogdir(char *progname); int sys_startgui(const char *guipath); int sys_rcfile(void); -int m_scheduler(void); +int m_mainloop(void); void sys_addhelppath(char *p); #ifdef USEAPI_ALSA void alsa_adddev(char *name); @@ -43,6 +43,7 @@ int sys_noloadbang; int sys_nogui; int sys_hipriority = -1; /* -1 = don't care; 0 = no; 1 = yes */ int sys_guisetportnumber; /* if started from the GUI, this is the port # */ +int sys_nosleep = 0; /* skip all "sleep" calls and spin instead */ char *sys_guicmd; t_symbol *sys_libdir; @@ -60,6 +61,7 @@ int sys_midioutdevlist[MAXMIDIOUTDEV] = {1}; char sys_font[100] = "courier"; /* tb: font name */ static int sys_main_srate; static int sys_main_advance; +static int sys_main_callback; static int sys_listplease; int sys_externalschedlib; @@ -69,7 +71,7 @@ char sys_extraflagsstring[MAXPDSTRING]; /* here the "-1" counts signify that the corresponding vector hasn't been - specified in command line arguments; sys_open_audio will detect this + specified in command line arguments; sys_set_audio_settings will detect it and fill things in. */ static int sys_nsoundin = -1; static int sys_nsoundout = -1; @@ -81,7 +83,6 @@ static int sys_nchout = -1; static int sys_chinlist[MAXAUDIOINDEV]; static int sys_choutlist[MAXAUDIOOUTDEV]; -int sys_nosleep = 0; /* skip all "sleep" calls and spin instead */ t_sample* get_sys_soundout() { return sys_soundout; } t_sample* get_sys_soundin() { return sys_soundin; } int* get_sys_main_advance() { return &sys_main_advance; } @@ -313,7 +314,7 @@ int sys_main(int argc, char **argv) sys_reopen_midi(); sys_reopen_audio(); /* run scheduler until it quits */ - return (m_scheduler()); + return (m_mainloop()); } } @@ -580,6 +581,11 @@ int sys_argparse(int argc, char **argv) sys_main_advance = atoi(argv[1]); argc -= 2; argv += 2; } + else if (!strcmp(*argv, "-callback")) + { + sys_main_callback = 1; + argc--; argv++; + } else if (!strcmp(*argv, "-blocksize")) { sys_setblocksize(atoi(argv[1])); @@ -899,7 +905,7 @@ static void sys_afterargparse(void) int i; int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; - int nchindev, nchoutdev, rate, advance; + int nchindev, nchoutdev, rate, advance, callback; int nmidiindev = 0, midiindev[MAXMIDIINDEV]; int nmidioutdev = 0, midioutdev[MAXMIDIOUTDEV]; /* add "extra" library to path */ @@ -935,7 +941,7 @@ static void sys_afterargparse(void) else are the default. Overwrite them with any results of argument parsing, and store them again. */ sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); if (sys_nchin >= 0) { nchindev = sys_nchin; @@ -981,8 +987,11 @@ static void sys_afterargparse(void) advance = sys_main_advance; if (sys_main_srate) rate = sys_main_srate; - sys_open_audio(naudioindev, audioindev, nchindev, chindev, - naudiooutdev, audiooutdev, nchoutdev, choutdev, rate, advance, 0); + if (sys_main_callback) + callback = sys_main_callback; + sys_set_audio_settings(naudioindev, audioindev, nchindev, chindev, + naudiooutdev, audiooutdev, nchoutdev, choutdev, rate, advance, + callback); sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 0); } diff --git a/pd/src/s_midi_pm.c b/pd/src/s_midi_pm.c index b0993268..831f3f06 100644 --- a/pd/src/s_midi_pm.c +++ b/pd/src/s_midi_pm.c @@ -21,7 +21,6 @@ #include "portaudio.h" #include "portmidi.h" #include "porttime.h" -#include "pminternal.h" static PmStream *mac_midiindevlist[MAXMIDIINDEV]; static PmStream *mac_midioutdevlist[MAXMIDIOUTDEV]; diff --git a/pd/src/s_stuff.h b/pd/src/s_stuff.h index 17974833..4cde9c42 100644 --- a/pd/src/s_stuff.h +++ b/pd/src/s_stuff.h @@ -71,10 +71,10 @@ extern int sys_blocksize; /* audio I/O block size in sample frames */ extern float sys_dacsr; extern int sys_schedadvance; extern int sys_sleepgrain; -void sys_open_audio(int naudioindev, int *audioindev, +void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, - int srate, int advance, int enable); + int srate, int advance, int callback); void sys_reopen_audio( void); void sys_close_audio(void); @@ -139,7 +139,11 @@ EXTERN void sys_log_error(int type); #define ERR_DACSLEPT 2 #define ERR_RESYNC 3 #define ERR_DATALATE 4 -void sched_set_using_dacs(int flag); + +#define SCHED_AUDIO_NONE 0 +#define SCHED_AUDIO_POLL 1 +#define SCHED_AUDIO_CALLBACK 2 +void sched_set_using_audio(int flag); /* s_inter.c */ @@ -205,9 +209,11 @@ void sys_setvirtualalarm( void); #define DEFAULTADVANCE 50 #endif +typedef void (*t_audiocallback)(void); + int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin, t_sample *soundout, int framesperbuf, int nbuffers, - int indeviceno, int outdeviceno); + int indeviceno, int outdeviceno, t_audiocallback callback); void pa_close_audio(void); int pa_send_dacs(void); void sys_reportidle(void); @@ -245,7 +251,7 @@ void jack_getdevs(char *indevlist, int *nindevs, int maxndev, int devdescsize); void jack_listdevs(void); -void mmio_open_audio(int naudioindev, int *audioindev, +int mmio_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate); void mmio_close_audio( void); @@ -269,11 +275,11 @@ void linux_alsa_devname(char *devname); void sys_get_audio_params( int *pnaudioindev, int *paudioindev, int *chindev, int *pnaudiooutdev, int *paudiooutdev, int *choutdev, - int *prate, int *padvance); + int *prate, int *padvance, int *callback); void sys_save_audio_params( int naudioindev, int *audioindev, int *chindev, int naudiooutdev, int *audiooutdev, int *choutdev, - int rate, int advance); + int rate, int advance, int callback); /* s_file.c */ diff --git a/pd/src/t_tkcmd.c b/pd/src/t_tkcmd.c index 61e66691..c32dc346 100644 --- a/pd/src/t_tkcmd.c +++ b/pd/src/t_tkcmd.c @@ -619,19 +619,11 @@ int Pdtcl_Init(Tcl_Interp *interp) { const char *argv = Tcl_GetVar(interp, "argv", 0); int portno, argno = 0; - /* argument passing seems to be different in MSW as opposed to - unix-likes. Here we check if we got sent a "port number" as an - argument. If so. we're to connect to a previously running pd (i.e., - pd got started first). If not, we start Pd from here. */ -#ifdef MSW if (argv && (portno = atoi(argv)) > 1) -#else - char *firstspace; - if (argv && (firstspace = strchr(argv, ' ')) && (portno = atoi(firstspace)) > 1) -#endif pdgui_setsock(portno); #ifdef DEBUGCONNECT - debugfd = fopen("/Users/msp/bratwurst", "w"); + pd_portno = portno; + debugfd = fopen("/tmp/bratwurst", "w"); fprintf(debugfd, "turning stderr back on\n"); fflush(debugfd); dup2(fileno(debugfd), 2); diff --git a/pd/src/u_main.tk b/pd/src/u_main.tk index b44aedab..2a736ca5 100644 --- a/pd/src/u_main.tk +++ b/pd/src/u_main.tk @@ -3479,7 +3479,7 @@ proc audio_apply {id} { global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4 global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4 global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4 - global audio_sr audio_advance + global audio_sr audio_advance audio_callback pd [concat pd audio-dialog \ $audio_indev1 \ @@ -3500,6 +3500,7 @@ proc audio_apply {id} { [expr $audio_outchan4 * ( $audio_outenable4 ? 1 : -1 ) ]\ $audio_sr \ $audio_advance \ + $audio_callback \ \;] } @@ -3543,14 +3544,15 @@ proc audio_popup {name buttonname varname devlist} { proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ inchan1 inchan2 inchan3 inchan4 \ outdev1 outdev2 outdev3 outdev4 \ - outchan1 outchan2 outchan3 outchan4 sr advance multi longform} { + outchan1 outchan2 outchan3 outchan4 sr advance multi callback \ + longform} { global audio_indev1 audio_indev2 audio_indev3 audio_indev4 global audio_inchan1 audio_inchan2 audio_inchan3 audio_inchan4 global audio_inenable1 audio_inenable2 audio_inenable3 audio_inenable4 global audio_outdev1 audio_outdev2 audio_outdev3 audio_outdev4 global audio_outchan1 audio_outchan2 audio_outchan3 audio_outchan4 global audio_outenable1 audio_outenable2 audio_outenable3 audio_outenable4 - global audio_sr audio_advance + global audio_sr audio_advance audio_callback global audio_indevlist audio_outdevlist global pd_indev pd_outdev @@ -3584,7 +3586,7 @@ proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ set audio_sr $sr set audio_advance $advance - + set audio_callback $callback toplevel $id wm title $id {audio} wm protocol $id WM_DELETE_WINDOW [concat audio_cancel $id] @@ -3597,9 +3599,10 @@ proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ -command "audio_apply $id" button $id.buttonframe.ok -text {OK}\ -command "audio_ok $id" - pack $id.buttonframe.cancel -side left -expand 1 - pack $id.buttonframe.apply -side left -expand 1 - pack $id.buttonframe.ok -side left -expand 1 + button $id.buttonframe.save -text {Save all settings}\ + -command "audio_apply $id \; pd pd save-preferences \\;" + pack $id.buttonframe.cancel $id.buttonframe.apply $id.buttonframe.ok \ + $id.buttonframe.save -side left -expand 1 # sample rate and advance frame $id.srf @@ -3610,7 +3613,11 @@ proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ label $id.srf.l2 -text "delay (msec):" entry $id.srf.x2 -textvariable audio_advance -width 4 pack $id.srf.l1 $id.srf.x1 $id.srf.l2 $id.srf.x2 -side left - + if {$audio_callback >= 0} { + checkbutton $id.srf.x3 -variable audio_callback \ + -text {use callbacks} -anchor e + pack $id.srf.x3 -side left + } # input device 1 frame $id.in1f pack $id.in1f -side top diff --git a/pd/src/x_arithmetic.c b/pd/src/x_arithmetic.c index 224636d8..c55e3ea8 100644 --- a/pd/src/x_arithmetic.c +++ b/pd/src/x_arithmetic.c @@ -581,9 +581,6 @@ typedef struct _atan2 static void *atan2_new(void) { t_atan2 *x = (t_atan2 *)pd_new(atan2_class); - static int warned; - if (!warned) - post("warning: atan2 inlets switched from Pd 0.37 to 0.38"), warned=1; floatinlet_new(&x->x_ob, &x->x_f); x->x_f = 0; outlet_new(&x->x_ob, &s_float); -- cgit v1.2.1