aboutsummaryrefslogtreecommitdiff
path: root/sndfiler
diff options
context:
space:
mode:
Diffstat (limited to 'sndfiler')
-rwxr-xr-xsndfiler/doc/sndfiler-help.pd71
-rwxr-xr-xsndfiler/src/sndfiler.c124
2 files changed, 142 insertions, 53 deletions
diff --git a/sndfiler/doc/sndfiler-help.pd b/sndfiler/doc/sndfiler-help.pd
index c05142e..fb402f7 100755
--- a/sndfiler/doc/sndfiler-help.pd
+++ b/sndfiler/doc/sndfiler-help.pd
@@ -1,48 +1,53 @@
-#N canvas 225 0 465 689 10;
+#N canvas 135 0 465 772 10;
#X obj 29 23 cnv 15 404 54 empty empty empty 22 25 0 18 -1 -66577 0
;
#X obj 31 25 cnv 15 400 50 empty empty sndfiler 22 25 0 18 -228992
-66577 0;
-#X obj 72 637 print THREADED_SF;
-#X obj 72 592 r \$0-tsf;
-#X obj 68 394 openpanel;
-#X obj 68 438 s \$0-tsf;
-#X obj 68 374 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+#X obj 55 667 print THREADED_SF;
+#X obj 55 622 r \$0-tsf;
+#X obj 48 440 openpanel;
+#X obj 48 484 s \$0-tsf;
+#X obj 48 420 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
-#X obj 258 615 table array1;
-#X text 89 373 <- read;
-#X obj 256 536 s \$0-tsf;
-#X msg 256 510 resize array1 4410;
-#X text 39 276 read a file: read filename array1 array2 ...;
-#X text 40 292 NOTE: this will also resize the array to the filesize
-!;
-#X text 66 340 for mono files:;
-#X msg 68 416 read \$1 array1;
-#X obj 239 396 openpanel;
-#X obj 239 440 s \$0-tsf;
-#X obj 239 376 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+#X obj 241 645 table array1;
+#X text 69 419 <- read;
+#X obj 239 566 s \$0-tsf;
+#X msg 239 540 resize array1 4410;
+#X text 46 386 for mono files:;
+#X obj 239 442 openpanel;
+#X obj 239 486 s \$0-tsf;
+#X obj 239 422 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
-1;
-#X text 260 375 <- read;
-#X text 235 340 for multichannel specify;
-#X text 237 353 more arrays:;
-#X msg 239 418 read \$1 array1 array2;
-#X obj 258 637 table array2;
-#X obj 72 615 sndfiler;
+#X text 260 421 <- read;
+#X text 235 386 for multichannel specify;
+#X text 237 399 more arrays:;
+#X msg 239 464 read \$1 array1 array2;
+#X obj 241 667 table array2;
+#X obj 55 645 sndfiler;
#X text 288 34 threaded soundfiler;
#X text 308 51 using libsndfile;
#X text 161 113 ::: SNDFILER :::;
-#X text 65 152 A threaded soundfiler for PD using libsndfile.;
+#X text 63 152 A threaded soundfiler for PD using libsndfile.;
#X text 65 182 REQUIREMENTS:;
#X text 118 199 - pd >= 0.39;
#X text 118 215 - libsndfile;
#X text 118 231 - threadlib (for main pd);
-#X text 65 509 threaded resize of arrays:;
-#X connect 3 0 23 0;
-#X connect 4 0 14 0;
+#X text 48 539 threaded resize of arrays:;
+#X text 33 267 read a file: read [flags] filename array1 array2 ...
+;
+#X msg 48 462 read -resize \$1 array1;
+#X text 32 287 FLAGS:;
+#X text 32 305 -resize: resize the array(s) to the size of the soundfile
+;
+#X text 33 324 -skip <sample>: skip nr. of samples in soundfile \,
+if negative \, it will be counted from the end of the file !;
+#X text 82 722 (c) 2005 \, Tim Blechmann \, Georg Holzmann;
+#X connect 3 0 20 0;
+#X connect 4 0 31 0;
#X connect 6 0 4 0;
#X connect 10 0 9 0;
-#X connect 14 0 5 0;
-#X connect 15 0 21 0;
-#X connect 17 0 15 0;
-#X connect 21 0 16 0;
-#X connect 23 0 2 0;
+#X connect 12 0 18 0;
+#X connect 14 0 12 0;
+#X connect 18 0 13 0;
+#X connect 20 0 2 0;
+#X connect 31 0 5 0;
diff --git a/sndfiler/src/sndfiler.c b/sndfiler/src/sndfiler.c
index c1579ee..80df1c9 100755
--- a/sndfiler/src/sndfiler.c
+++ b/sndfiler/src/sndfiler.c
@@ -236,18 +236,37 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv)
int i, j;
int channel_count;
t_float** helper_arrays;
+ int resize = 0;
+ int seek = 0, arraysize = 0, writesize;
t_symbol* file;
t_garray ** arrays;
SNDFILE* sndfile;
SF_INFO info;
-
- if (argc < 2)
+
+ // parse flags
+ while (argc > 0 && argv->a_type == A_SYMBOL &&
+ *argv->a_w.w_symbol->s_name == '-')
{
- pd_error(x, "usage: read soundfile array1 array2 ...");
- return;
+ char *flag = argv->a_w.w_symbol->s_name + 1;
+ if (!strcmp(flag, "resize"))
+ {
+ resize = 1;
+ argc -= 1; argv += 1;
+ }
+ else if (!strcmp(flag, "skip"))
+ {
+ if (argc < 2 || argv[1].a_type != A_FLOAT ||
+ ((seek = argv[1].a_w.w_float) == 0))
+ goto usage;
+ argc -= 2; argv += 2;
+ }
+ else goto usage;
}
+
+ if (argc < 2)
+ goto usage;
file = atom_getsymbolarg(0, argc, argv);
@@ -257,41 +276,83 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv)
arrays = getbytes(channel_count * sizeof(t_garray*));
for (i = 0; i != channel_count; ++i)
{
- t_garray * array = (t_garray *)pd_findbyclass(atom_getsymbolarg(i+1,
- argc, argv), garray_class);
-
- if (array)
- arrays[i] = array;
- else
- {
- pd_error(x, "%s: no such array", atom_getsymbolarg(i+1, argc, argv)->s_name);
- return;
- }
+ t_float *dummy;
+ int size;
+ t_garray *array;
+
+ if(!(array = (t_garray *)pd_findbyclass(
+ atom_getsymbolarg(i+1, argc, argv), garray_class)))
+ {
+ pd_error(x, "%s: no such array", atom_getsymbolarg(i+1,
+ argc, argv)->s_name);
+ return;
+ }
+
+ if(garray_getfloatarray(array, &size, &dummy))
+ arrays[i] = array;
+ else
+ {
+ pd_error(x, "%s: bad template for sndfiler", atom_getsymbolarg(i+1,
+ argc, argv)->s_name);
+ return;
+ }
+
+ // in multichannel mode: check if arrays have different length
+ if (arraysize && arraysize != size && !resize)
+ {
+ post("sndfiler: arrays have different lengths, resizing to last one ...");
+ }
+ arraysize = size;
}
- post("sndfiler: loading file ...");
-
sndfile = sf_open(file->s_name, SFM_READ, &info);
if (sndfile)
{
+ int pos = 0;
int maxchannels = (channel_count < info.channels) ?
channel_count : info.channels;
t_float * item = alloca(maxchannels * sizeof(t_float));
t_int ** syncdata = getbytes(sizeof(t_int*) * 5);
-
+
+ // negative seek: offset from the end of the file
+ if(seek<0)
+ {
+ pos = sf_seek(sndfile, seek, SEEK_END);
+ }
+ if(seek>0)
+ {
+ pos = sf_seek(sndfile, seek, SEEK_SET);
+ }
+ if(pos == -1)
+ {
+ pd_error(x, "invalid seek in soundfile");
+ return;
+ }
+
+ if(resize)
+ {
+ writesize = (info.frames-pos);
+ arraysize = writesize;
+ }
+ else
+ writesize = (arraysize>(info.frames-pos)) ?
+ info.frames-pos : arraysize;
+
+ post("sndfiler: loading file ...");
+
#if (_POSIX_MEMLOCK - 0) >= 200112L
munlockall();
#endif
for (i = 0; i != channel_count; ++i)
{
- helper_arrays[i] = getalignedbytes(info.frames * sizeof(t_float));
+ helper_arrays[i] = getalignedbytes(arraysize * sizeof(t_float));
}
- for (i = 0; i != info.frames; ++i)
+ for (i = 0; i != writesize; ++i)
{
sf_read_float(sndfile, item, info.channels);
@@ -303,6 +364,21 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv)
}
}
}
+
+ // fill remaining elements with zero
+ if(!resize && (arraysize>(info.frames-pos)))
+ {
+ for (i = writesize; i != arraysize; ++i)
+ {
+ for (j = 0; j != info.channels; ++j)
+ {
+ if (j < channel_count)
+ {
+ helper_arrays[j][i] = 0;
+ }
+ }
+ }
+ }
#if (_POSIX_MEMLOCK - 0) >= 200112L
mlockall(MCL_FUTURE);
@@ -313,13 +389,21 @@ static void sndfiler_read_cb(t_sndfiler * x, int argc, t_atom* argv)
syncdata[0] = (t_int*)arrays;
syncdata[1] = (t_int*)helper_arrays;
syncdata[2] = (t_int*)channel_count;
- syncdata[3] = (t_int*)(long)info.frames;
+ syncdata[3] = (t_int*)arraysize;
syncdata[4] = (t_int*)x;
sys_callback(sndfiler_synchonize, (t_int*)syncdata, 5);
+ return;
}
else
+ {
pd_error(x, "Error opening file");
+ return;
+ }
+
+ usage:
+ pd_error(x, "usage: read [flags] filename array1 array2 ...");
+ post("flags: -skip <n> -resize ");
}
static t_int sndfiler_synchonize(t_int * w)