diff --git a/pd/src/configure.in b/pd/src/configure.in index ca68c45ff19296d26c14dd64050765128aee237b..b378e0761bbc1026c3b06e28024fd7f4857d9916 100644 --- a/pd/src/configure.in +++ b/pd/src/configure.in @@ -47,8 +47,10 @@ AC_ARG_ENABLE(setuid, [ --enable-setuid install as setuid (linux)], setuid=$enableval) AC_ARG_ENABLE(fftw, [ --enable-fftw use FFTW package], fftw=$enableval) -AC_ARG_ENABLE(fat, [ --disable-fat build fat binary on Mac OS X], +AC_ARG_ENABLE(fat, [ --disable-fat build fat binary on Mac OS X], fat=$enableval, fat="yes") +AC_ARG_ENABLE(tk, [ --disable-tk build without tcl/tk-GUI], + tk=$enableval) dnl Checks for programs. AC_PROG_CC @@ -96,8 +98,8 @@ AC_CHECK_LIB(pthread, pthread_create,PDLIB="$PDLIB -lpthread", dnl Check for fftw package if test x$fftw = "xyes"; then -AC_CHECK_LIB(fftw, fftw_one,PDLIB="$PDLIB -lfftw", - echo "fftw package not found - using built-in FFT"; fftw=no) +AC_CHECK_LIB(fftw3f, fftwf_version,PDLIB="$PDLIB -lfftw3f", + echo "fftw3 package not found - using built-in FFT"; fftw=no) fi dnl look for tcl 8.x... do I really have to go through all this!? @@ -176,13 +178,10 @@ else GUISRC= fi -# leave the executable as 'pd' on Mac OS X and Windows, but call it -# 'pdl2ork' on GNU/Linux -PDEXEC=pd +PDEXEC=pd-l2ork -if test `uname -s` = Linux; +if test `uname -s` = Linux -o `uname -s` = "GNU/kFreeBSD" -o `uname -s` = "GNU"; then - PDEXEC=pd-l2ork dnl Ckecking for ALSA echo .................... alsa= $alsa dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. @@ -206,7 +205,16 @@ dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. CPPFLAGS="-DDL_OPEN -DPA_USE_OSS -DUNIX -DUNISTD\ -DUSEAPI_OSS \ -fno-strict-aliasing" - SYSSRC="s_midi_oss.c s_audio_oss.c" +dnl No OSS on hurd + if test `uname -s` = "GNU"; + then + SYSSRC="s_midi_dummy.c" + else + SYSSRC="s_midi_oss.c s_audio_oss.c" + CPPFLAGS=$CPPFLAGS" -DPA_USE_OSS -DUSEAPI_OSS" + fi + + if test x$alsa = "xyes"; then SYSSRC=$SYSSRC" s_audio_alsa.c s_audio_alsamm.c s_midi_alsa.c" @@ -223,7 +231,6 @@ dnl This should be fixed so Pd can use ALSA shared libraries where appropriate. -I../portmidi/pm_common \ -I../portmidi/pm_linux" SYSSRC="s_audio_pa.c \ - s_audio_pablio.c \ s_audio_paring.c \ ../portaudio/src/common/pa_allocation.c \ ../portaudio/src/common/pa_converters.c \ @@ -281,7 +288,7 @@ then -framework AudioUnit -framework AudioToolbox \ -framework Carbon -framework CoreMIDI" EXT=pd_darwin - CPPFLAGS="-DDL_OPEN -DMACOSX -DUNISTD -I/usr/X11R6/include \ + CPPFLAGS="-DHAVE_LIBDL -DMACOSX -DHAVE_UNISTD_H -I/usr/X11R6/include \ -I../portaudio/include -I../portaudio/src/common \ -I../portaudio/src/os/mac_osx/ \ -I../portmidi/pm_common -I../portmidi/pm_mac \ @@ -303,7 +310,6 @@ then EXTERNTARGET=d_ppc fi SYSSRC="s_midi_pm.c s_audio_pa.c \ - s_audio_pablio.c \ s_audio_paring.c \ ../portaudio/src/common/pa_allocation.c \ ../portaudio/src/common/pa_converters.c \ @@ -323,8 +329,6 @@ then ../portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c \ ../portmidi/pm_mac/pmmac.c \ ../portmidi/pm_mac/pmmacosxcm.c \ - ../portmidi/pm_mac/finddefault.c \ - ../portmidi/pm_mac/readbinaryplist.c \ ../portmidi/pm_common/pmutil.c \ ../portmidi/pm_common/portmidi.c \ ../portmidi/porttime/ptmacosx_cf.c " @@ -357,7 +361,7 @@ then OSNUMBER=2 if test x$jack = "xyes"; then - LDFLAGS=$LDFLAGS" -weak_framework Jackmp" + LDFLAGS=$LDFLAGS" -weak_framework Jackmp" fi if test x$jack = "xrun"; then @@ -377,7 +381,7 @@ then -mwindows -mms-bitfields "$MORECFLAGS PDLIB=$PDLIB" -lwsock32 -lwinmm -lole32 -lstdc++" - SYSSRC="s_audio_pa.c s_audio_pablio.c s_audio_paring.c \ + SYSSRC="s_audio_pa.c s_audio_paring.c \ s_audio_mmio.c s_midi_mmio.c \ ../portaudio/src/common/pa_allocation.c \ ../portaudio/src/common/pa_converters.c \ @@ -418,7 +422,7 @@ fi if test x$fftw = "xyes"; then SYSSRC=$SYSSRC" d_fft_fftw.c d_fftroutine.c" - LDFLAGS=$LDFLAGS" -lfftw" + LDFLAGS=$LDFLAGS" -lfftw3" else SYSSRC=$SYSSRC" d_fft_mayer.c d_fftroutine.c" fi diff --git a/pd/src/d_fft_fftw.c b/pd/src/d_fft_fftw.c index 0ead62be4397ca1d1d49f3d570e7a5ff4c164863..04e4729deecccc26ca3e57d36229b8eb4c16147f 100644 --- a/pd/src/d_fft_fftw.c +++ b/pd/src/d_fft_fftw.c @@ -4,31 +4,32 @@ /* --------- Pd interface to FFTW library; imitate Mayer API ---------- */ -#include "m_pd.h" -#ifdef MSW -#include <malloc.h> -#else -#include <alloca.h> -#endif - -#error oops -- I'm talking to the old fftw. Apparently it's still changing. +/* changes and additions for FFTW3 by Thomas Grill */ -#include <fftw.h> +#include "m_pd.h" +#include <fftw3.h> int ilog2(int n); -#define MINFFT 5 +#define MINFFT 0 #define MAXFFT 30 /* from the FFTW website: - fftw_complex in[N], out[N]; + #include <fftw3.h> + ... + { + fftw_complex *in, *out; fftw_plan p; ... - p = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE); + in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); + out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); + p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); ... - fftw_one(p, in, out); + fftw_execute(p); ... fftw_destroy_plan(p); + fftw_free(in); fftw_free(out); + } FFTW_FORWARD or FFTW_BACKWARD, and indicates the direction of the transform you are interested in. Alternatively, you can use the sign of the exponent in the @@ -37,57 +38,126 @@ respectively. The flags argument is either FFTW_MEASURE */ -static fftw_plan fftw_pvec[2 * (MAXFFT+1 - MINFFT)]; +/* complex stuff */ + +typedef struct { + fftwf_plan plan; + fftwf_complex *in,*out; +} cfftw_info; + +static cfftw_info cfftw_fwd[MAXFFT+1 - MINFFT],cfftw_bwd[MAXFFT+1 - MINFFT]; + +static cfftw_info *cfftw_getplan(int n,int fwd) +{ + cfftw_info *info; + int logn = ilog2(n); + if (logn < MINFFT || logn > MAXFFT) + return (0); + info = (fwd?cfftw_fwd:cfftw_bwd)+(logn-MINFFT); + if (!info->plan) + { + info->in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * n); + info->out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * n); + info->plan = fftwf_plan_dft_1d(n, info->in, info->out, fwd?FFTW_FORWARD:FFTW_BACKWARD, FFTW_MEASURE); + } + return info; +} + -static fftw_plan fftw_getplan(int n, int dir) +/* real stuff */ + +typedef struct { + fftwf_plan plan; + float *in,*out; +} rfftw_info; + +static rfftw_info rfftw_fwd[MAXFFT+1 - MINFFT],rfftw_bwd[MAXFFT+1 - MINFFT]; + +static rfftw_info *rfftw_getplan(int n,int fwd) { - logn = ilog2(n); + rfftw_info *info; + int logn = ilog2(n); if (logn < MINFFT || logn > MAXFFT) return (0); - int indx = 2*(logn-MINFFT) + inverse); - if (!fftw_pvec[indx] - fftw_pvec[indx] = fftw_create_plan(N, dir, FFTW_MEASURE); - return (fftw_pvec[indx]); + info = (fwd?rfftw_fwd:rfftw_bwd)+(logn-MINFFT); + if (!info->plan) + { + info->in = (float*) fftwf_malloc(sizeof(float) * n); + info->out = (float*) fftwf_malloc(sizeof(float) * n); + info->plan = fftwf_plan_r2r_1d(n, info->in, info->out, fwd?FFTW_R2HC:FFTW_HC2R, FFTW_MEASURE); + } + return info; } + + EXTERN void mayer_fht(float *fz, int n) { post("FHT: not yet implemented"); } -static void mayer_dofft(int n, float *fz1, float *fz2, int dir) +static void mayer_do_cfft(int n, float *fz1, float *fz2, int fwd) { - float *inbuf, *outbuf, *fp1, *fp2, *fp3; int i; - fftw_plan p = fftw_getplan(n, dir); - inbuf = alloca(n * (4 * sizeof(float))); - outbuf = inbuf + 2*n; + float *fz; + cfftw_info *p = cfftw_getplan(n, fwd); if (!p) return; - for (i = 0, fp1 = fz1, fp2 = fz2, fp3 = inbuf; i < n; i++) - fp3[0] = *fp1++, fp3[1] = *fp2++, fp3 += 2; - fftw_one(p, inbuf, outbuf); - for (i = 0, fp1 = fz1, fp2 = fz2, fp3 = outbuf; i < n; i++) - *fp1++ = fp3[0], *fp2++ = fp3[1], fp3 += 2; + + for (i = 0, fz = (float *)p->in; i < n; i++) + fz[i*2] = fz1[i], fz[i*2+1] = fz2[i]; + + fftwf_execute(p->plan); + + for (i = 0, fz = (float *)p->out; i < n; i++) + fz1[i] = fz[i*2], fz2[i] = fz[i*2+1]; } EXTERN void mayer_fft(int n, float *fz1, float *fz2) { - mayer_dofft(n, fz1, fz2, FFTW_FORWARD); + mayer_do_cfft(n, fz1, fz2, 1); } EXTERN void mayer_ifft(int n, float *fz1, float *fz2) { - mayer_dofft(n, fz1, fz2, FFTW_BACKWARD); + mayer_do_cfft(n, fz1, fz2, 0); } +/* + in the following the sign flips are done to + be compatible with the mayer_fft implementation, + but it's probably the mayer_fft that should be corrected... +*/ + EXTERN void mayer_realfft(int n, float *fz) { - post("rfft: not yet implemented"); + int i; + rfftw_info *p = rfftw_getplan(n, 1); + if (!p) + return; + + for (i = 0; i < n; i++) + p->in[i] = fz[i]; + fftwf_execute(p->plan); + for (i = 0; i < n/2+1; i++) + fz[i] = p->out[i]; + for (; i < n; i++) + fz[i] = -p->out[i]; } EXTERN void mayer_realifft(int n, float *fz) { - post("rifft: not yet implemented"); + int i; + rfftw_info *p = rfftw_getplan(n, 0); + if (!p) + return; + + for (i = 0; i < n/2+1; i++) + p->in[i] = fz[i]; + for (; i < n; i++) + p->in[i] = -fz[i]; + fftwf_execute(p->plan); + for (i = 0; i < n; i++) + fz[i] = p->out[i]; }