From bc96a98d953afbee541b5e5b5bbcfc99f86842bb Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Mon, 28 Nov 2005 22:27:20 +0000 Subject: new flags: -resize and -skip svn path=/trunk/externals/tb/; revision=4073 --- sndfiler/doc/sndfiler-help.pd | 71 +++++++++++++----------- sndfiler/src/sndfiler.c | 124 +++++++++++++++++++++++++++++++++++------- 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 : 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 -resize "); } static t_int sndfiler_synchonize(t_int * w) -- cgit v1.2.1