[PD] pd music
patrick
puredata at 11h11.com
Fri Jan 5 00:10:23 CET 2007
hi,
actually i am not using sfwrite~ for this track, my recording
application was timemachine (linux only / jack). but it produces a WAV
in 32bit float IEEE that no pd external is able to read the header
information (samples, samplerate, channels etc).
i did look at the source (see below) of soundfile_info (iem) but i am
not sure where to start...
/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000
- 2005 */
#ifdef _MSC_VER
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#include "m_pd.h"
#include "iemlib.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#define SFI_HEADER_SAMPLERATE 0
#define SFI_HEADER_FILENAME 1
#define SFI_HEADER_MULTICHANNEL_FILE_LENGTH 2
#define SFI_HEADER_HEADERBYTES 3
#define SFI_HEADER_CHANNELS 4
#define SFI_HEADER_BYTES_PER_SAMPLE 5
#define SFI_HEADER_ENDINESS 6
#define SFI_HEADER_SIZE 7
/* --------------------------- soundfile_info
-------------------------------- */
/* -- reads only header of a wave-file and outputs the important
parameters -- */
static t_class *soundfile_info_class;
typedef struct _soundfile_info
{
t_object x_obj;
long *x_begmem;
int x_size;
t_atom x_atheader[SFI_HEADER_SIZE];
t_canvas *x_canvas;
void *x_list_out;
} t_soundfile_info;
static short soundfile_info_str2short(char *cvec)
{
short s=0;
unsigned char *uc=(unsigned char *)cvec;
s += (short)(*uc);
s += (short)(*(uc+1)*256);
return(s);
}
static long soundfile_info_str2long(char *cvec)
{
long l=0;
unsigned char *uc=(unsigned char *)cvec;
l += (long)(*uc);
l += (long)(*(uc+1)*256);
l += (long)(*(uc+2)*65536);
l += (long)(*(uc+3)*16777216);
return(l);
}
static void soundfile_info_read(t_soundfile_info *x, t_symbol *filename)
{
char completefilename[400];
int i, n, n2, n4, filesize, read_chars, header_size=0, ch, bps, sr;
FILE *fh;
t_atom *at;
char *cvec;
long ll;
short ss;
if(filename->s_name[0] == '/')/*make complete path + filename*/
{
strcpy(completefilename, filename->s_name);
}
else if(((filename->s_name[0] >= 'A')&&(filename->s_name[0] <= 'Z')||
(filename->s_name[0] >= 'a')&&(filename->s_name[0] <= 'z'))&&
(filename->s_name[1] == ':')&&(filename->s_name[2] == '/'))
{
strcpy(completefilename, filename->s_name);
}
else
{
strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name);
strcat(completefilename, "/");
strcat(completefilename, filename->s_name);
}
fh = fopen(completefilename,"rb");
if(!fh)
{
post("soundfile_info_read: cannot open %s !!\n", completefilename);
}
else
{
n = x->x_size;
n2 = sizeof(short) * x->x_size;
n4 = sizeof(long) * x->x_size;
fseek(fh, 0, SEEK_END);
filesize = ftell(fh);
fseek(fh,0,SEEK_SET);
read_chars = (int)fread(x->x_begmem, sizeof(char), n4, fh) /2;
fclose(fh);
// post("read chars = %d", read_chars);
cvec = (char *)x->x_begmem;
if(read_chars > 4)
{
if(strncmp(cvec, "RIFF", 4))
{
post("soundfile_info_read-error: %s is no RIFF-WAVE-file",
completefilename);
goto soundfile_info_end;
}
header_size += 8;
cvec += 8;
if(strncmp(cvec, "WAVE", 4))
{
post("soundfile_info_read-error: %s is no RIFF-WAVE-file",
completefilename);
goto soundfile_info_end;
}
header_size += 4;
cvec += 4;
for(i=header_size/2; i<read_chars; i++)
{
if(!strncmp(cvec, "fmt ", 4))
goto soundfile_info_fmt;
header_size += 2;
cvec += 2;
}
post("soundfile_info_read-error: %s has at begin no
format-chunk", completefilename);
goto soundfile_info_end;
soundfile_info_fmt:
header_size += 4;
cvec += 4;
ll = soundfile_info_str2long(cvec);
if(ll != 16)
{
post("soundfile_info_read-error: %s has a format-chunk not
equal to 16", completefilename);
goto soundfile_info_end;
}
header_size += 4;
cvec += 4;
ss = soundfile_info_str2short(cvec);
/* format */
if(ss != 1) /* PCM = 1 */
{
post("soundfile_info_read-error: %s is not PCM-format coded",
completefilename);
goto soundfile_info_end;
}
header_size += 2;
cvec += 2;
ss = soundfile_info_str2short(cvec);
/* channels */
if((ss < 1) || (ss > 100))
{
post("soundfile_info_read-error: %s has no common
channel-number", completefilename);
goto soundfile_info_end;
}
SETFLOAT(x->x_atheader+SFI_HEADER_CHANNELS, (float)ss);
ch = ss;
header_size += 2;
cvec += 2;
ll = soundfile_info_str2long(cvec);
/* samplerate */
if((ll > 400000) || (ll < 200))
{
post("soundfile_info_read-error: %s has no common samplerate",
completefilename);
goto soundfile_info_end;
}
SETFLOAT(x->x_atheader+SFI_HEADER_SAMPLERATE, (float)ll);
sr = ll;
header_size += 4;
cvec += 4;
header_size += 4; /* bytes_per_sec */
cvec += 4;
ss = soundfile_info_str2short(cvec);
/* bytes_per_sample */
if((ss < 1) || (ss > 100))
{
post("soundfile_info_read-error: %s has no common number of
bytes per sample", completefilename);
goto soundfile_info_end;
}
SETFLOAT(x->x_atheader+SFI_HEADER_BYTES_PER_SAMPLE, (float)(ss/ch));
bps = ss;
header_size += 2;
cvec += 2;
header_size += 2; /* bits_per_sample */
cvec += 2;
for(i=header_size/2; i<read_chars; i++)
{
if(!strncmp(cvec, "data", 4))
goto soundfile_info_data;
header_size += 2;
cvec += 2;
}
post("soundfile_info_read-error: %s has at begin no data-chunk",
completefilename);
goto soundfile_info_end;
soundfile_info_data:
header_size += 8;
cvec += 8;
SETFLOAT(x->x_atheader+SFI_HEADER_HEADERBYTES, (float)header_size);
filesize -= header_size;
filesize /= bps;
SETFLOAT(x->x_atheader+SFI_HEADER_MULTICHANNEL_FILE_LENGTH,
(float)filesize);
SETSYMBOL(x->x_atheader+SFI_HEADER_ENDINESS, gensym("l"));
SETSYMBOL(x->x_atheader+SFI_HEADER_FILENAME,
gensym(completefilename));
/* post("ch = %d", ss);
post("sr = %d", ll);
post("bps = %d", ss/ch);
post("head = %d", header_size);
post("len = %d", filesize);*/
outlet_list(x->x_list_out, &s_list, SFI_HEADER_SIZE, x->x_atheader);
soundfile_info_end:
;
}
}
}
static void soundfile_info_free(t_soundfile_info *x)
{
freebytes(x->x_begmem, x->x_size * sizeof(long));
}
static void *soundfile_info_new(void)
{
t_soundfile_info *x = (t_soundfile_info *)pd_new(soundfile_info_class);
x->x_size = 10000;
x->x_begmem = (long *)getbytes(x->x_size * sizeof(long));
x->x_list_out = outlet_new(&x->x_obj, &s_list);
x->x_canvas = canvas_getcurrent();
return (x);
}
/* ---------------- global setup function -------------------- */
void soundfile_info_setup(void)
{
soundfile_info_class = class_new(gensym("soundfile_info"),
(t_newmethod)soundfile_info_new,
(t_method)soundfile_info_free, sizeof(t_soundfile_info), 0, 0);
class_addmethod(soundfile_info_class, (t_method)soundfile_info_read,
gensym("read"), A_SYMBOL, 0);
class_sethelpsymbol(soundfile_info_class,
gensym("iemhelp/help-soundfile_info"));
}
oups, sorry it's a little bit long.
pat
More information about the Pd-list
mailing list