diff options
Diffstat (limited to 'iemlib1/src')
-rw-r--r-- | iemlib1/src/soundfile_info.c | 135 |
1 files changed, 68 insertions, 67 deletions
diff --git a/iemlib1/src/soundfile_info.c b/iemlib1/src/soundfile_info.c index 1a84403..654f71a 100644 --- a/iemlib1/src/soundfile_info.c +++ b/iemlib1/src/soundfile_info.c @@ -1,7 +1,7 @@ /* 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 - 2008 */ +iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2010 */ #include "m_pd.h" #include "iemlib.h" @@ -20,6 +20,7 @@ iemlib1 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2008 #define SFI_HEADER_FORMAT_CODE 7 #define SFI_HEADER_SIZE 8 +#define SFI_HEADER_CHUNK_SIZE_ESTIMATION 10000 @@ -32,43 +33,43 @@ typedef struct _soundfile_info { t_object x_obj; long *x_begmem; - int x_size; - t_atom x_atheader[SFI_HEADER_SIZE]; + int x_mem_size; + t_atom x_at_header[SFI_HEADER_SIZE]; t_canvas *x_canvas; void *x_list_out; } t_soundfile_info; -static short soundfile_info_str2short(char *cvec) +static short soundfile_info_string_to_int16(char *cvec) { - short s=0; + short ss=0; unsigned char *uc=(unsigned char *)cvec; - s += (short)(*uc); - s += (short)(*(uc+1)*256); - return(s); + ss += (short)(*uc); + ss += (short)(*(uc+1)*256); + return(ss); } -static long soundfile_info_str2long(char *cvec) +static unsigned long soundfile_info_string_to_uint32(char *cvec) { - long l=0; + unsigned long ul=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); + ul += (unsigned long)(*uc); + ul += (unsigned long)(*(uc+1)*256); + ul += (unsigned long)(*(uc+2)*65536); + ul += (unsigned long)(*(uc+3)*16777216); + return(ul); } 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; + int i, n, n2, n4, filesize, read_chars, header_size=0, ch, bytesperframe, sr, n_frames; FILE *fh; t_atom *at; char *cvec; - long ll; - short ss; + unsigned long ul_chunk_size, ul_sr; + short ss_format, ss_ch, ss_bytesperframe; if(filename->s_name[0] == '/')/*make complete path + filename*/ { @@ -94,13 +95,13 @@ static void soundfile_info_read(t_soundfile_info *x, t_symbol *filename) } else { - n = x->x_size; - n2 = sizeof(short) * x->x_size; - n4 = sizeof(long) * x->x_size; + n = x->x_mem_size; // 10000 bytes + n2 = sizeof(short) * x->x_mem_size; + n4 = sizeof(long) * x->x_mem_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; + 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; @@ -111,7 +112,7 @@ static void soundfile_info_read(t_soundfile_info *x, t_symbol *filename) post("soundfile_info_read-error: %s is no RIFF-WAVE-file", completefilename); goto soundfile_info_end; } - header_size += 8; + header_size += 8; // jump over RIFF chunk size cvec += 8; if(strncmp(cvec, "WAVE", 4)) { @@ -124,7 +125,11 @@ static void soundfile_info_read(t_soundfile_info *x, t_symbol *filename) for(i=header_size/2; i<read_chars; i++) { if(!strncmp(cvec, "fmt ", 4)) + { + header_size += 4; + cvec += 4; goto soundfile_info_fmt; + } header_size += 2; cvec += 2; } @@ -132,68 +137,65 @@ static void soundfile_info_read(t_soundfile_info *x, t_symbol *filename) goto soundfile_info_end; soundfile_info_fmt: - header_size += 4; - cvec += 4; - ll = soundfile_info_str2long(cvec); - if(ll != 16) + ul_chunk_size = soundfile_info_string_to_uint32(cvec); + if(ul_chunk_size < 16) { - post("soundfile_info_read-error: %s has a format-chunk not equal to 16", completefilename); + post("soundfile_info_read-error: %s has a format-chunk less than 16", completefilename); goto soundfile_info_end; } header_size += 4; cvec += 4; - ss = soundfile_info_str2short(cvec); - /* format */ - if((ss != 1) && (ss != 3) && (ss != 6) && (ss != 7)) /* PCM = 1 ; IEEE-FLOAT = 3 ; ALAW = 6 ; MULAW = 7 */ + + ss_format = soundfile_info_string_to_int16(cvec); + if((ss_format != 1) && (ss_format != 3) && (ss_format != 6) && (ss_format != 7) && (ss_format != -2)) /* PCM = 1 ; IEEE-FLOAT = 3 ; ALAW = 6 ; MULAW = 7 ; WAVE_EX = -2 */ { post("soundfile_info_read-error: %s has unknown format code", completefilename); goto soundfile_info_end; } - SETFLOAT(x->x_atheader+SFI_HEADER_FORMAT_CODE, (t_float)ss); + SETFLOAT(x->x_at_header+SFI_HEADER_FORMAT_CODE, (t_float)ss_format); header_size += 2; cvec += 2; - ss = soundfile_info_str2short(cvec); - /* channels */ - if((ss < 1) || (ss > 1000)) + + ss_ch = soundfile_info_string_to_int16(cvec); /* channels */ + if((ss_ch < 1) || (ss_ch > 32000)) { post("soundfile_info_read-error: %s has no common channel-number", completefilename); goto soundfile_info_end; } - SETFLOAT(x->x_atheader+SFI_HEADER_CHANNELS, (t_float)ss); - ch = ss; + SETFLOAT(x->x_at_header+SFI_HEADER_CHANNELS, (t_float)ss_ch); + ch = (int)ss_ch; header_size += 2; cvec += 2; - ll = soundfile_info_str2long(cvec); - /* samplerate */ - if((ll > 400000) || (ll < 200)) + + ul_sr = soundfile_info_string_to_uint32(cvec); /* samplerate */ + if((ul_sr > 2000000000) || (ul_sr < 1)) { post("soundfile_info_read-error: %s has no common samplerate", completefilename); goto soundfile_info_end; } - SETFLOAT(x->x_atheader+SFI_HEADER_SAMPLERATE, (t_float)ll); - sr = ll; + SETFLOAT(x->x_at_header+SFI_HEADER_SAMPLERATE, (t_float)ul_sr); + sr = (int)ul_sr; header_size += 4; cvec += 4; - header_size += 4; /* bytes_per_sec */ + header_size += 4; /* jump over bytes_per_sec */ cvec += 4; - ss = soundfile_info_str2short(cvec); - - /* bytes_per_sample */ - if((ss < 1) || (ss > 100)) + + ss_bytesperframe = soundfile_info_string_to_int16(cvec); /* bytes_per_frame */ + if((ss_bytesperframe < 1) || (ss_bytesperframe > 32000)) { - post("soundfile_info_read-error: %s has no common number of bytes per sample", completefilename); + post("soundfile_info_read-error: %s has no common number of bytes per frame", completefilename); goto soundfile_info_end; } - SETFLOAT(x->x_atheader+SFI_HEADER_BYTES_PER_SAMPLE, (t_float)(ss/ch)); - bps = ss; + SETFLOAT(x->x_at_header+SFI_HEADER_BYTES_PER_SAMPLE, (t_float)(ss_bytesperframe / ss_ch)); + bytesperframe = (int)ss_bytesperframe; header_size += 2; cvec += 2; - header_size += 2; /* bits_per_sample */ + header_size += 2; /* jump over bits_per_sample */ cvec += 2; - for(i=header_size/2; i<read_chars; i++) + for(i=header_size/2; i<read_chars; i++) // looking for data chunk { if(!strncmp(cvec, "data", 4)) goto soundfile_info_data; @@ -204,24 +206,23 @@ soundfile_info_fmt: goto soundfile_info_end; soundfile_info_data: - header_size += 8; + header_size += 8; // ignore data chunk size cvec += 8; - SETFLOAT(x->x_atheader+SFI_HEADER_HEADERBYTES, (t_float)header_size); + SETFLOAT(x->x_at_header+SFI_HEADER_HEADERBYTES, (t_float)header_size); - filesize -= header_size; - filesize /= bps; - SETFLOAT(x->x_atheader+SFI_HEADER_MULTICHANNEL_FILE_LENGTH, (t_float)filesize); - SETSYMBOL(x->x_atheader+SFI_HEADER_ENDINESS, gensym("l")); - SETSYMBOL(x->x_atheader+SFI_HEADER_FILENAME, gensym(completefilename)); + n_frames = (filesize - header_size) / bytesperframe; + SETFLOAT(x->x_at_header+SFI_HEADER_MULTICHANNEL_FILE_LENGTH, (t_float)n_frames); + SETSYMBOL(x->x_at_header+SFI_HEADER_ENDINESS, gensym("l")); + SETSYMBOL(x->x_at_header+SFI_HEADER_FILENAME, gensym(completefilename)); - /* post("ch = %d", ss); - post("sr = %d", ll); - post("bps = %d", ss/ch); + /* post("ch = %d", ch); + post("sr = %d", sr); + post("bpf = %d", bytesperframe/ch); post("head = %d", header_size); - post("len = %d", filesize);*/ + post("len = %d", n_frames);*/ - outlet_list(x->x_list_out, &s_list, SFI_HEADER_SIZE, x->x_atheader); + outlet_list(x->x_list_out, &s_list, SFI_HEADER_SIZE, x->x_at_header); soundfile_info_end: @@ -233,15 +234,15 @@ soundfile_info_end: static void soundfile_info_free(t_soundfile_info *x) { - freebytes(x->x_begmem, x->x_size * sizeof(long)); + freebytes(x->x_begmem, x->x_mem_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_mem_size = SFI_HEADER_CHUNK_SIZE_ESTIMATION; /* try to read the first 10000 bytes of the soundfile */ + x->x_begmem = (long *)getbytes(x->x_mem_size * sizeof(long)); x->x_list_out = outlet_new(&x->x_obj, &s_list); x->x_canvas = canvas_getcurrent(); return (x); |