From 506b8e7dedb80d79bf015e47d92e8b8dd8284584 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sat, 16 Aug 2003 17:08:55 +0000 Subject: added files straight from Yves' sources svn path=/trunk/externals/unauthorized/; revision=864 --- samplebox~/CHANGES.LOG | 6 + samplebox~/INSTALL | 9 + samplebox~/Makefile | 97 ++++++++ samplebox~/README | 19 ++ samplebox~/help-samplebox~.pd | 145 ++++++++++++ samplebox~/samplebox~.c | 529 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 805 insertions(+) create mode 100644 samplebox~/CHANGES.LOG create mode 100644 samplebox~/INSTALL create mode 100644 samplebox~/Makefile create mode 100644 samplebox~/README create mode 100644 samplebox~/help-samplebox~.pd create mode 100644 samplebox~/samplebox~.c (limited to 'samplebox~') diff --git a/samplebox~/CHANGES.LOG b/samplebox~/CHANGES.LOG new file mode 100644 index 0000000..e83144d --- /dev/null +++ b/samplebox~/CHANGES.LOG @@ -0,0 +1,6 @@ +0.3 + Reworked allocation +0.2 + Reworked interpolation +0.1 + First implementation diff --git a/samplebox~/INSTALL b/samplebox~/INSTALL new file mode 100644 index 0000000..c0dc546 --- /dev/null +++ b/samplebox~/INSTALL @@ -0,0 +1,9 @@ +untar in /my/pd/dir/externs + +cd /my/pd/dir/externs/samplebox~ + +make + +make install + +you're set !! diff --git a/samplebox~/Makefile b/samplebox~/Makefile new file mode 100644 index 0000000..72194fe --- /dev/null +++ b/samplebox~/Makefile @@ -0,0 +1,97 @@ +NAME=samplebox~ +CSYM=samplebox_tilde + +current: pd_linux + +# ----------------------- NT ----------------------- + +pd_nt: $(NAME).dll + +.SUFFIXES: .dll + +PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo +VC="C:\Program Files\Microsoft Visual Studio\Vc98" + +PDNTINCLUDE = /I. /I\tcl\include /I\ftp\pd\src /I$(VC)\include + +PDNTLDIR = $(VC)\lib +PDNTLIB = $(PDNTLDIR)\libc.lib \ + $(PDNTLDIR)\oldnames.lib \ + $(PDNTLDIR)\kernel32.lib \ + \ftp\pd\bin\pd.lib + +.c.dll: + cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c + link /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) + +# ----------------------- IRIX 5.x ----------------------- + +pd_irix5: $(NAME).pd_irix5 + +.SUFFIXES: .pd_irix5 + +SGICFLAGS5 = -o32 -DPD -DUNIX -DIRIX -O2 + +SGIINCLUDE = -I../../src + +.c.pd_irix5: + cc $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c + ld -elf -shared -rdata_shared -o $*.pd_irix5 $*.o + rm $*.o + +# ----------------------- IRIX 6.x ----------------------- + +pd_irix6: $(NAME).pd_irix6 + +.SUFFIXES: .pd_irix6 + +SGICFLAGS6 = -n32 -DPD -DUNIX -DIRIX -DN32 -woff 1080,1064,1185 \ + -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \ + -Ofast=ip32 + +.c.pd_irix6: + cc $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c + ld -n32 -IPA -shared -rdata_shared -o $*.pd_irix6 $*.o + rm $*.o + +# ----------------------- LINUX i386 ----------------------- + +pd_linux: $(NAME).pd_linux + +.SUFFIXES: .pd_linux + +LINUXCFLAGS = -DPD -DUNIX -DICECAST -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wshadow -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch + +LINUXINCLUDE = -I../../src + +.c.pd_linux: + cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + ld -export_dynamic -shared -o $*.pd_linux $*.o -lc -lm + strip --strip-unneeded $*.pd_linux + rm -f $*.o ../$*.pd_linux + ln -s $*/$*.pd_linux .. + +# ----------------------- Mac OSX ----------------------- + +pd_darwin: $(NAME).pd_darwin + +.SUFFIXES: .pd_darwin + +DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ + -Wno-unused -Wno-parentheses -Wno-switch + +.c.pd_darwin: + cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c + cc -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o + rm -f $*.o ../$*.pd_darwin + ln -s $*/$*.pd_darwin .. + +# ---------------------------------------------------------- + +install: + cp help-*.pd ../../doc/5.reference + +clean: + rm -f *.o *.pd_* so_locations diff --git a/samplebox~/README b/samplebox~/README new file mode 100644 index 0000000..06bb14c --- /dev/null +++ b/samplebox~/README @@ -0,0 +1,19 @@ +Version 0.01 +copyleft 2001 by Yves Degoyon +tarballs and updates available @ http://ydegoyon.free.fr + +samplebox~.dll : an opaque box to record and playback a sound ( with speed variations ) + +To install sonograph~, follow the steps from INSTALL + +This software is published under GPL terms. + +This is software with ABSOLUTELY NO WARRANTY. +Use it at your OWN RISK. It's possible to damage e.g. hardware or your hearing +due to a bug or for other reasons. +We do not warrant that the program is free of infringement of any third-party +patents. + +***************************************************************************** + + diff --git a/samplebox~/help-samplebox~.pd b/samplebox~/help-samplebox~.pd new file mode 100644 index 0000000..9b5b6f5 --- /dev/null +++ b/samplebox~/help-samplebox~.pd @@ -0,0 +1,145 @@ +#N canvas 19 6 986 684 10; +#X obj 126 505 dac~; +#X msg 183 318 record; +#X msg 271 39 play; +#X obj 342 252 hsl 128 15 0 100 0 0 empty empty empty 20 8 0 8 -262144 +-1 -1 0 1; +#X text 309 250 0 %; +#X text 476 251 100 %; +#X obj 343 270 hsl 128 15 0 100 0 0 empty empty empty 20 8 0 8 -262144 +-1 -1 12700 1; +#X text 310 271 0 %; +#X text 478 269 100 %; +#X msg 352 504 \; pd dsp 1; +#X msg 414 505 \; pd dsp 0; +#X text 606 251 Start Point; +#X text 608 269 End Point; +#X msg 19 21 bang; +#X obj 19 41 openpanel; +#X obj 19 187 soundfiler; +#X msg 15 306 bang; +#X msg 512 271 100; +#X obj 544 270 loadbang; +#X text 19 546 3s * samplerate / blocksize ( 3*44100/64 = 2067 ); +#X floatatom 49 207 10 0 0; +#X obj 18 207 / 64; +#X msg 122 207 resize \$1; +#X obj 19 63 t s b; +#X text 35 592 Comments and bugs @ ydegoyon@free.fr; +#X obj 65 63 float \$0; +#X obj 19 80 route float; +#X msg 339 318 flipblocks; +#X text 410 318 Flip blocks ( reverse effect ); +#X msg 338 294 swapblocks 0 50 20; +#X text 23 5 Step 1 : Load a sound file; +#X msg 274 132 phase \$1; +#X obj 365 130 hsl 128 15 0 90 0 0 empty empty empty 20 8 0 8 -262144 +-1 -1 0 1; +#X obj 273 62 hsl 128 15 0 100 0 0 empty empty empty 20 8 0 8 -262144 +-1 -1 0 1; +#X text 247 63 0 %; +#X text 407 62 100 %; +#X obj 274 81 hsl 128 15 0 100 0 0 empty empty empty 20 8 0 8 -262144 +-1 -1 12700 1; +#X text 248 84 0 %; +#X text 409 80 100 %; +#X text 551 61 Start Point; +#X text 552 80 End Point; +#X msg 443 78 100; +#X obj 470 78 loadbang; +#X text 630 69 Playback positions; +#X msg 268 103 readspeed \$1; +#X floatatom 399 103 5 0 0; +#X text 553 101 Reading speed; +#X obj 358 103 / 100; +#X msg 448 104 100; +#X obj 477 104 loadbang; +#X obj 223 447 samplebox~ 2067; +#X text 16 282 Step 2 : Record the sound; +#X text 276 15 Step 3 : Play back recorded sound; +#X text 341 222 Step 4 : modify parts of the sound; +#X text 474 293 Swap sections [0% \, 20%] and [50% \, 70%] of [start +\, end]; +#X text 21 533 Note : initially \, this is a 3 seconds samplebox~ : +; +#X text 34 581 Samplebox records and plays back a sound; +#X text 342 235 Set portions of the sound to modify; +#X text 500 132 100%; +#X text 341 131 0%; +#X obj 44 100 makefilename %d-leftsample; +#X obj 511 512 table \$0-leftsample; +#X obj 650 511 table \$0-rightsample; +#X obj 45 123 makefilename %d-rightsample; +#X obj 20 149 pack s s s; +#X msg 19 170 read -resize \$1 \$2 \$3; +#X obj 16 343 tabplay~ \$0-leftsample; +#X obj 80 363 tabplay~ \$0-rightsample; +#X obj 278 474 print recordend; +#X obj 399 472 print playend; +#X text 552 127 Switch channels ( use as pan for mono input ); +#X msg 456 159 bang; +#X text 557 161 Ping-pong ( requires countund object ); +#X obj 305 160 countund 90; +#X obj 113 481 *~; +#X obj 144 479 / 100; +#X floatatom 74 447 5 0 0; +#X obj 184 478 *~; +#X obj 211 477 / 100; +#X obj 384 159 metro 100; +#X obj 28 423 loadbang; +#X msg 28 449 100; +#X connect 1 0 50 0; +#X connect 2 0 50 0; +#X connect 3 0 50 4; +#X connect 6 0 50 5; +#X connect 13 0 14 0; +#X connect 14 0 23 0; +#X connect 15 0 21 0; +#X connect 16 0 1 0; +#X connect 16 0 66 0; +#X connect 16 0 67 0; +#X connect 17 0 6 0; +#X connect 18 0 17 0; +#X connect 20 0 22 0; +#X connect 21 0 20 0; +#X connect 22 0 50 0; +#X connect 23 0 64 0; +#X connect 23 1 25 0; +#X connect 25 0 26 0; +#X connect 26 0 60 0; +#X connect 26 0 63 0; +#X connect 27 0 50 0; +#X connect 29 0 50 0; +#X connect 31 0 50 0; +#X connect 32 0 31 0; +#X connect 33 0 50 2; +#X connect 36 0 50 3; +#X connect 41 0 36 0; +#X connect 42 0 41 0; +#X connect 44 0 50 0; +#X connect 45 0 47 0; +#X connect 47 0 44 0; +#X connect 48 0 45 0; +#X connect 49 0 48 0; +#X connect 50 0 74 0; +#X connect 50 1 77 0; +#X connect 50 2 68 0; +#X connect 50 3 69 0; +#X connect 50 3 2 0; +#X connect 60 0 64 1; +#X connect 63 0 64 2; +#X connect 64 0 65 0; +#X connect 65 0 15 0; +#X connect 66 0 50 0; +#X connect 67 0 50 1; +#X connect 71 0 79 0; +#X connect 73 0 31 0; +#X connect 74 0 0 0; +#X connect 75 0 74 1; +#X connect 76 0 75 0; +#X connect 76 0 78 0; +#X connect 77 0 0 1; +#X connect 78 0 77 1; +#X connect 79 0 73 0; +#X connect 80 0 81 0; +#X connect 81 0 76 0; diff --git a/samplebox~/samplebox~.c b/samplebox~/samplebox~.c new file mode 100644 index 0000000..e276df5 --- /dev/null +++ b/samplebox~/samplebox~.c @@ -0,0 +1,529 @@ +/*------------------------ samplebox~ ----------------------------------------- */ +/* */ +/* samplebox~ : records and plays back a sound */ +/* Written by Yves Degoyon ( ydegoyon@free.fr ) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* See file LICENSE for further informations on licensing terms. */ +/* */ +/* 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 for more details. */ +/* */ +/* You should have received a copy of the GNU General Public License */ +/* along with this program; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* */ +/* Based on PureData by Miller Puckette and others. */ +/* */ +/* All i wanted is your time */ +/* All you gave me was tomorrow */ +/* But, tomorrow never comes, tomorrow never comes */ +/* Vini Reilly -- "Tomorrow" */ +/* ---------------------------------------------------------------------------- */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef UNIX +#include +#endif +#ifdef NT +#define M_PI 3.14159265358979323846 +#endif +#include + +#include "m_pd.h" /* standard pd stuff */ + +static char *samplebox_version = "samplebox~: stores and plays back a sound version 0.3, written by Yves Degoyon (ydegoyon@free.fr)"; + + +static t_class *samplebox_class; + +typedef struct _samplebox +{ + t_object x_obj; + + t_int x_size; /* size of the stored sound ( in blocks~ ) */ + t_float x_samplerate; /* sample rate */ + t_int x_blocksize; /* current block size ( might be modified by block~ object ) */ + t_float x_readpos; /* data's playing position */ + t_int x_writepos; /* data's recording position */ + t_int x_readstart; /* data's starting position for reading */ + t_int x_readend; /* data's ending position for reading */ + t_int x_modstart; /* data's starting position for modifications */ + t_int x_modend; /* data's ending position for modifications */ + t_int x_play; /* playing on/off flag */ + t_float x_readspeed; /* number of grouped blocks for reading */ + t_float x_record; /* flag to start recording process */ + t_float x_allocate; /* flag to avoid reading data during generation */ + t_float *x_rdata; /* table containing left channel of the sound */ + t_float *x_idata; /* table containing right channel of the sound */ + t_float *x_rootsquares; /* sum of the root squares of a block ( energy ) */ + t_float x_phase; /* phase to apply on output */ + t_outlet *x_recordend; /* outlet for end of recording */ + t_outlet *x_playend; /* outlet for end of playing back */ + t_float x_f; /* float needed for signal input */ + +} t_samplebox; + + /* clean up */ +static void samplebox_free(t_samplebox *x) +{ + if ( x->x_rdata != NULL ) { + freebytes(x->x_rdata, x->x_size*x->x_blocksize*sizeof(float) ); + post( "Freed %d bytes", x->x_size*x->x_blocksize*sizeof(float) ); + x->x_rdata = NULL; + } + if ( x->x_idata != NULL ) { + freebytes(x->x_idata, x->x_size*x->x_blocksize*sizeof(float) ); + post( "Freed %d bytes", x->x_size*x->x_blocksize*sizeof(float) ); + x->x_idata = NULL; + } + if ( x->x_rootsquares != NULL ) { + freebytes(x->x_rootsquares, x->x_size*sizeof(float) ); + post( "Freed %d bytes", x->x_size*sizeof(float) ); + x->x_rootsquares = NULL; + } +} + + /* allocate tables for storing sound */ +static t_int samplebox_allocate(t_samplebox *x) +{ + if ( !(x->x_rdata = getbytes( x->x_size*x->x_blocksize*sizeof(float) ) ) ) { + return -1; + } else { + post( "samplebox~ : allocated %d bytes", x->x_size*x->x_blocksize*sizeof(float) ); + } + if ( !(x->x_idata = getbytes( x->x_size*x->x_blocksize*sizeof(float) ) ) ) { + return -1; + } else { + post( "samplebox~ : allocated %d bytes", x->x_size*x->x_blocksize*sizeof(float) ); + } + if ( !(x->x_rootsquares = getbytes( x->x_size*sizeof(float) ) ) ) { + return -1; + } else { + post( "samplebox~ : allocated %d bytes", x->x_size*sizeof(float) ); + } + return 0; +} + + /* reallocate tables for storing sound */ +static t_int samplebox_reallocate(t_samplebox *x, t_int ioldsize, t_int inewsize) +{ + t_float *prdata=x->x_rdata, *pidata=x->x_idata, *prootsquares=x->x_rootsquares; + + if ( !(x->x_rdata = getbytes( inewsize*x->x_blocksize*sizeof(float) ) ) ) { + return -1; + } else { + post( "samplebox~ : allocated %d bytes", inewsize*x->x_blocksize*sizeof(float) ); + } + if ( !(x->x_idata = getbytes( inewsize*x->x_blocksize*sizeof(float) ) ) ) { + return -1; + } else { + post( "samplebox~ : allocated %d bytes", inewsize*x->x_blocksize*sizeof(float) ); + } + if ( !(x->x_rootsquares = getbytes( inewsize*sizeof(float) ) ) ) { + return -1; + } else { + post( "samplebox~ : allocated %d bytes", inewsize*sizeof(float) ); + } + if ( prdata != NULL ) { + freebytes(prdata, ioldsize*x->x_blocksize*sizeof(float) ); + post( "Freed %d bytes", ioldsize*x->x_blocksize*sizeof(float) ); + } + if ( pidata != NULL ) { + freebytes(pidata, ioldsize*x->x_blocksize*sizeof(float) ); + post( "Freed %d bytes", ioldsize*x->x_blocksize*sizeof(float) ); + } + if ( prootsquares != NULL ) { + freebytes(prootsquares, ioldsize*sizeof(float) ); + post( "Freed %d bytes", ioldsize*sizeof(float) ); + } + return 0; +} + + /* records or playback the sonogram */ +static t_int *samplebox_perform(t_int *w) +{ + t_float *rin = (t_float *)(w[1]); + t_float *iin = (t_float *)(w[2]); + t_float *rout = (t_float *)(w[3]); + t_float *iout = (t_float *)(w[4]); + t_float fspectrum = 0.0; + t_float fphase = 0.0; + t_int rpoint; + t_int n = (int)(w[5]); /* number of samples */ + t_samplebox *x = (t_samplebox *)(w[6]); + t_int bi; + t_float v[4]; + t_float z[4]; + + // reallocate tables if blocksize has been changed + if ( n != x->x_blocksize ) { + post( "samplebox~ : reallocating tables" ); + x->x_allocate = 1; + samplebox_free(x); + x->x_blocksize = n; + samplebox_allocate(x); + x->x_allocate = 0; + } + + // new block : energy is set to zero + // if ( x->x_record ) { + // *(x->x_rootsquares+x->x_writepos) = 0.0; + // } + + if ( x->x_play || x->x_record ) { + bi = 0; + while (bix_allocate && x->x_record) { + *(x->x_rdata+(x->x_writepos*x->x_blocksize)+bi)=*rin; + *(x->x_idata+(x->x_writepos*x->x_blocksize)+bi)=*iin; + // *(x->x_rootsquares+x->x_writepos) += sqrt( pow((*rin),2) + pow((*iin),2) ); + } + // set outputs + if ( !x->x_allocate && x->x_play) { + *rout = 0.; + *iout = 0.; + // interpolates 4 points like tabread4 + rpoint = ((int)x->x_readpos*x->x_blocksize)+bi; + + if ( rpoint == 0 ) { + v[0]=0.0; + v[1]=*(x->x_rdata+rpoint); + v[2]=*(x->x_rdata+rpoint+1); + v[3]=*(x->x_rdata+rpoint+2); + z[0]=0.0; + z[1]=*(x->x_idata+rpoint); + z[2]=*(x->x_idata+rpoint+1); + z[3]=*(x->x_idata+rpoint+2); + } else if ( rpoint == (x->x_size*x->x_blocksize-1) ) { + v[0]=*(x->x_rdata+rpoint-1); + v[1]=*(x->x_rdata+rpoint); + v[2]=*(x->x_rdata+rpoint+1); + v[3]=0.0; + z[0]=*(x->x_idata+rpoint-1); + z[1]=*(x->x_idata+rpoint); + z[2]=*(x->x_idata+rpoint+1); + z[3]=0.0; + } else if ( rpoint == (x->x_size*x->x_blocksize) ) { + v[0]=*(x->x_rdata+rpoint-1); + v[1]=*(x->x_rdata+rpoint); + v[2]=0.0; + v[3]=0.0; + z[0]=*(x->x_idata+rpoint-1); + z[1]=*(x->x_idata+rpoint); + z[2]=0.0; + z[3]=0.0; + } else { + v[0]=*(x->x_rdata+rpoint-1); + v[1]=*(x->x_rdata+rpoint); + v[2]=*(x->x_rdata+rpoint+1); + v[3]=*(x->x_rdata+rpoint+2); + z[0]=*(x->x_idata+rpoint-1); + z[1]=*(x->x_idata+rpoint); + z[2]=*(x->x_idata+rpoint+1); + z[3]=*(x->x_idata+rpoint+2); + } + + { + t_float frac = rpoint-(int)rpoint; + + // taken from tabread4_tilde + *rout = v[1]+frac*((v[2]-v[1])-0.5f*(frac-1.)*((v[0]-v[3]+3.0f*(v[2]-v[1]))*frac+(2.0f*v[1]-v[0]-v[2]))); + *iout = z[1]+frac*((z[2]-z[1])-0.5f*(frac-1.)*((z[0]-z[3]+3.0f*(z[2]-z[1]))*frac+(2.0f*z[1]-z[0]-z[2]))); + } + + // add phase argument + fspectrum = sqrt( pow( *rout, 2) + pow( *iout, 2) ); + fphase = atan2( *iout, *rout ); + fphase += (x->x_phase/180.0)*(M_PI); + *rout = fspectrum*cos( fphase ); + *iout = fspectrum*sin( fphase ); + } else { + *rout=0.0; + *iout=0.0; + } + rout++;iout++; + rin++;iin++; + bi++; + } + // reset playing position until next play + if ( x->x_play ) { + x->x_readpos+=x->x_readspeed; + // post( "xreadpos : %f (added %f)", x->x_readpos, x->x_readspeed ); + if ( x->x_readpos >= (x->x_readend*x->x_size)/100 ) { + x->x_play=0; + x->x_readpos=(x->x_readstart*x->x_size)/100; + // post( "samplebox~ : stopped playing (readpos=%d)", x->x_readpos ); + outlet_bang(x->x_playend); + } + } + // reset recording position until next record + if ( x->x_record ) { + x->x_writepos++; + if ( x->x_writepos >= x->x_size ) { + x->x_record=0; + x->x_writepos=0; + outlet_bang(x->x_recordend); + // post( "samplebox~ : stopped recording" ); + } + } + } + return (w+7); +} + +static void samplebox_dsp(t_samplebox *x, t_signal **sp) +{ + dsp_add(samplebox_perform, 6, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n, x); +} + + /* record the sonogram */ +static void samplebox_record(t_samplebox *x) +{ + x->x_record=1; + x->x_writepos=0; +} + + /* play the sonogram */ +static void samplebox_play(t_samplebox *x) +{ + x->x_play=1; + // reset read position + x->x_readpos=(x->x_readstart*x->x_size)/100; +} + + /* setting the starting point for reading ( in percent ) */ +static void samplebox_readstart(t_samplebox *x, t_floatarg fstart) +{ + t_float startpoint = fstart; + + if (startpoint < 0) startpoint = 0; + if (startpoint > 100) startpoint = 100; + if ( startpoint > x->x_readend ) { + x->x_readstart = x->x_readend; + post( "samplebox~ : warning : range for reading is null" ); + } else { + x->x_readstart=startpoint; + } +} + + /* setting the starting point for modification ( in percent ) */ +static void samplebox_modstart(t_samplebox *x, t_floatarg fstart) +{ + t_float startpoint = fstart; + + if (startpoint < 0) startpoint = 0; + if (startpoint > 100) startpoint = 100; + if ( startpoint > x->x_modend ) { + x->x_modstart = x->x_modend; + post( "samplebox~ : warning : range for modifications is null" ); + } else { + x->x_modstart=startpoint; + } +} + + /* setting the ending point for reading ( in percent ) */ +static void samplebox_readend(t_samplebox *x, t_floatarg fend) +{ + t_float endpoint = fend; + + if (endpoint < 0) endpoint = 0; + if (endpoint > 100) endpoint = 100; + if ( endpoint < x->x_readstart ) { + x->x_readend = x->x_readstart; + post( "samplebox~ : warning : range for reading is null" ); + } else { + x->x_readend=endpoint; + } +} + + /* setting the ending point for modification ( in percent ) */ +static void samplebox_modend(t_samplebox *x, t_floatarg fend) +{ + t_float endpoint = fend; + + if (endpoint < 0) endpoint = 0; + if (endpoint > 100) endpoint = 100; + if ( endpoint < x->x_modstart ) { + x->x_modend = x->x_modstart; + post( "samplebox~ : warning : range for modifications is null" ); + } else { + x->x_modend=endpoint; + } +} + + /* sets the reading speed */ +static void samplebox_readspeed(t_samplebox *x, t_floatarg freadspeed) +{ + if ((int)freadspeed < 0 ) { + post( "samplebox~ : wrong readspeed argument" ); + } + x->x_readspeed=freadspeed; +} + + /* resize sonogram */ +static void samplebox_resize(t_samplebox *x, t_floatarg fnewsize ) +{ + if (fnewsize <= 0) { + post( "samplebox~ : error : wrong size" ); + return; + } + post( "samplebox~ : reallocating tables" ); + x->x_record = 0; + x->x_play = 0; + x->x_allocate = 1; + samplebox_reallocate(x, x->x_size, fnewsize); + x->x_size = fnewsize; + x->x_allocate = 0; +} + + /* flip blocks */ +static void samplebox_flipblocks(t_samplebox *x) +{ + t_int samplestart, sampleend, middlesample, fi, si; + t_float fvalue; + + samplestart=(x->x_modstart*(x->x_size-1))/100; + sampleend=(x->x_modend*(x->x_size-1))/100; + middlesample = ( sampleend+samplestart+1 ) / 2; + post( "flip blocks [%d,%d] and [%d,%d]", samplestart, middlesample, middlesample, sampleend ); + + for ( si=samplestart; si<=middlesample; si++ ) { + for ( fi=0; fix_blocksize; fi++ ) { + fvalue = *(x->x_rdata+((si)*x->x_blocksize)+fi); + *(x->x_rdata+((si)*x->x_blocksize)+fi) = *(x->x_rdata+((sampleend+samplestart-si)*x->x_blocksize)+fi); + *(x->x_rdata+((sampleend+samplestart-si)*x->x_blocksize)+fi) = fvalue; + fvalue = *(x->x_idata+((si)*x->x_blocksize)+fi); + *(x->x_idata+((si)*x->x_blocksize)+fi) = *(x->x_idata+((sampleend+samplestart-si)*x->x_blocksize)+fi); + *(x->x_idata+((sampleend+samplestart-si)*x->x_blocksize)+fi) = fvalue; + } + } +} + + /* change the phase */ +static void samplebox_phase(t_samplebox *x, t_floatarg fincphase) +{ + if (fincphase < 0 || fincphase > 90) { + post( "samplebox~ : error : wrong phase in phase function : out of [0,90]" ); + return; + } + x->x_phase = fincphase; +} + + /* swap blocks */ +static void samplebox_swapblocks(t_samplebox *x, t_floatarg fperstart, t_floatarg fperend, t_floatarg fpersize) +{ + t_int samplestart, samplestartb, samplesize, sp, sf; + t_int iperstart, iperend, ipersize; + t_float s1, s2; + t_float fvalue; + + iperstart = fperstart; + iperend = fperend; + ipersize = fpersize; + + if (iperstart < 0 || iperstart > iperend || + iperend <= 0 || iperend+ipersize > 100 || + ipersize < 0 || fpersize > 100 ) { + post( "samplebox~ : error : wrong interval [%d%%, %d%%] <-> [%d%%, %d%%]", + iperstart, iperstart+ipersize, iperend, iperend+ipersize ); + return; + } + samplestart=(x->x_modstart*(x->x_size-1))/100; + samplestartb=(x->x_modend*(x->x_size-1))/100; + samplesize=((samplestartb-samplestart)*ipersize)/100; + samplestart=samplestart+((samplestartb-samplestart)*iperstart)/100; + samplestartb=samplestart+((samplestartb-samplestart)*iperend)/100; + + // post( "swap blocks [%d,%d] and [%d,%d]", samplestart, samplestart+samplesize, samplestartb, samplestartb+samplesize ); + + for ( sp=samplesize; sp>=0; sp-- ) { + for ( sf=0; sfx_blocksize; sf++) { + fvalue = *(x->x_rdata+((int)(samplestart+sp)*x->x_blocksize)+sf); + *(x->x_rdata+((int)(samplestart+sp)*x->x_blocksize)+sf) = *(x->x_rdata+((int)(samplestartb+sp)*x->x_blocksize)+sf); + *(x->x_rdata+((int)(samplestartb+sp)*x->x_blocksize)+sf) = fvalue; + fvalue = *(x->x_idata+((int)(samplestart+sp)*x->x_blocksize)+sf); + *(x->x_idata+((int)(samplestart+sp)*x->x_blocksize)+sf) = *(x->x_idata+((int)(samplestartb+sp)*x->x_blocksize)+sf); + *(x->x_idata+((int)(samplestartb+sp)*x->x_blocksize)+sf) = fvalue; + } + } +} + +static void *samplebox_new(t_floatarg fsize) +{ + t_samplebox *x = (t_samplebox *)pd_new(samplebox_class); + outlet_new(&x->x_obj, &s_signal); + outlet_new(&x->x_obj, &s_signal); + x->x_recordend = outlet_new(&x->x_obj, &s_bang ); + x->x_playend = outlet_new(&x->x_obj, &s_bang ); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("readstart")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("readend")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("modstart")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("modend")); + + if ( fsize <= 0 ) { + error( "samplebox~ : missing or negative creation arguments" ); + return NULL; + } + + x->x_size = fsize; + x->x_blocksize = sys_getblksize(); + x->x_play = 0; + x->x_readspeed = 1.; + x->x_record = 0; + x->x_readpos = 0.; + x->x_writepos = 0; + x->x_modstart = 0; + x->x_readstart = 0; + x->x_modend = 100; + x->x_readend = 100; + x->x_allocate = 0; + x->x_rdata = NULL; + x->x_idata = NULL; + x->x_rootsquares = NULL; + x->x_phase = 0.0; + x->x_samplerate = sys_getsr(); + if ( samplebox_allocate(x) <0 ) { + return NULL; + } else { + return(x); + } +} + +void samplebox_tilde_setup(void) +{ + post(samplebox_version); + samplebox_class = class_new(gensym("samplebox~"), (t_newmethod)samplebox_new, (t_method)samplebox_free, + sizeof(t_samplebox), 0, A_DEFFLOAT, 0); + class_sethelpsymbol( samplebox_class, gensym("help-samplebox~.pd") ); + CLASS_MAINSIGNALIN( samplebox_class, t_samplebox, x_f ); + class_addmethod(samplebox_class, (t_method)samplebox_dsp, gensym("dsp"), 0); + class_addmethod(samplebox_class, (t_method)samplebox_record, gensym("record"), 0); + class_addmethod(samplebox_class, (t_method)samplebox_resize, gensym("resize"), A_FLOAT, 0); + class_addmethod(samplebox_class, (t_method)samplebox_swapblocks, gensym("swapblocks"), A_FLOAT, A_FLOAT, A_FLOAT, 0); + class_addmethod(samplebox_class, (t_method)samplebox_flipblocks, gensym("flipblocks"), 0); + class_addmethod(samplebox_class, (t_method)samplebox_play, gensym("play"), 0); + class_addmethod(samplebox_class, (t_method)samplebox_phase, gensym("phase"), A_FLOAT, 0); + class_addmethod(samplebox_class, (t_method)samplebox_modstart, gensym("modstart"), A_FLOAT, 0); + class_addmethod(samplebox_class, (t_method)samplebox_modend, gensym("modend"), A_FLOAT, 0); + class_addmethod(samplebox_class, (t_method)samplebox_readstart, gensym("readstart"), A_FLOAT, 0); + class_addmethod(samplebox_class, (t_method)samplebox_readend, gensym("readend"), A_FLOAT, 0); + class_addmethod(samplebox_class, (t_method)samplebox_readspeed, gensym("readspeed"), A_FLOAT, 0); +} -- cgit v1.2.1