aboutsummaryrefslogtreecommitdiff
path: root/wavinfo.c
blob: 1f5d2f960a397c1fb1a3a4a54c46fce8b6babbb1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "ext13.h"
#include "m_pd.h"
#include "g_canvas.h"
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>

#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif

/*--*/

/* -------------------------- wavinfo ------------------------------ */
#define BLOCKTIME 0.001
#define uint32 unsigned int
#define uint16 unsigned short

typedef struct _wave
{
    char  w_fileid[4];              /* chunk id 'RIFF'            */
    uint32 w_chunksize;             /* chunk size                 */
    char  w_waveid[4];              /* wave chunk id 'WAVE'       */
    char  w_fmtid[4];               /* format chunk id 'fmt '     */
    uint32 w_fmtchunksize;          /* format chunk size          */
    uint16  w_fmttag;               /* format tag, 1 for PCM      */
    uint16  w_nchannels;            /* number of channels         */
    uint32 w_samplespersec;         /* sample rate in hz          */
    uint32 w_navgbytespersec;       /* average bytes per second   */
    uint16  w_nblockalign;          /* number of bytes per sample */
    uint16  w_nbitspersample;       /* number of bits in a sample */
    char  w_datachunkid[4];         /* data chunk id 'data'       */
    uint32 w_datachunksize;         /* length of data chunk       */
} t_wave;


static t_class *wavinfo_class;

typedef struct _wavinfo
{
    t_object x_obj;
    t_glist  *x_glist;
    t_float  x_samplerate;
    t_float  x_bitspersample;
    t_float  x_channels;
    t_float  x_length;
    t_float  x_nsamples;
    int      x_fd;
    t_symbol *x_s;
    t_outlet *x_out0;
    t_outlet *x_out1;
    t_outlet *x_out2;
    t_outlet *x_out3;
} t_wavinfo;


static void *wavinfo_new(t_symbol *s)
{
    t_wavinfo *x = (t_wavinfo *)pd_new(wavinfo_class);
    x->x_glist = (t_glist*) canvas_getcurrent();
    x->x_s = s;
//    outlet_new(&x->x_obj, &s_float);
    x->x_out0 = outlet_new(&x->x_obj, &s_float);
    x->x_out1 = outlet_new(&x->x_obj, &s_float);
    x->x_out2 = outlet_new(&x->x_obj, &s_float);
    x->x_out3 = outlet_new(&x->x_obj, &s_float); 
    return (x);
}

static void wavinfo_bang(t_wavinfo *x)
{
//  outlet_float(x->x_obj.ob_outlet, x->x_f);
}

static void wavinfo_symbol(t_wavinfo *x, t_symbol *filename)
{
   struct stat statbuf;
   t_wave* wavinfo;
   int result;
   char fname[MAXPDSTRING];
   int ok=(stat(filename->s_name, &statbuf) >= 0);
   if (ok>0) {
       canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,fname, MAXPDSTRING);
       if ((x->x_fd = open(fname,( O_NONBLOCK | O_RDONLY))) < 0)
       {
            error("can't open %s",fname);
            return;
       }

       wavinfo = getbytes(sizeof(t_wave));

       result=read (x->x_fd,wavinfo,sizeof(t_wave));
       if (result > 0){
        if (strncmp(wavinfo->w_waveid,"WAVE",4)==0){
            x->x_samplerate=(t_float)wavinfo->w_samplespersec;
            x->x_bitspersample=(t_float)wavinfo->w_nbitspersample;
            x->x_channels=(t_float)wavinfo->w_nchannels;
            x->x_length=(t_float)wavinfo->w_datachunksize;
            x->x_nsamples= x->x_length / (x->x_channels * x->x_bitspersample) * 8;
            outlet_float(x->x_out3,x->x_samplerate);
            outlet_float(x->x_out2,x->x_bitspersample);
            outlet_float(x->x_out1,x->x_channels);
            outlet_float(x->x_out0,x->x_nsamples);
        }else{
              error("not a valid wave-file");
        }
       }else{
             error("could not read wav-header");
       } 
       close (x->x_fd);
   }
   else post ("wavinfo:file not found");
}

void wavinfo_setup(void)
{
    wavinfo_class = class_new(gensym("wavinfo"), (t_newmethod)wavinfo_new, 0,
    	sizeof(t_wavinfo), 0, A_DEFFLOAT, 0);
    class_addcreator((t_newmethod)wavinfo_new, gensym("fsize"), A_DEFFLOAT, 0);
    class_addbang(wavinfo_class, wavinfo_bang);
    class_addsymbol(wavinfo_class, wavinfo_symbol);        
}