26 static t_class
*sfwrite_class
;
28 typedef struct _sfwrite
43 static void sfwrite_wave_setup(t_sfwrite
* x
,t_wave
* w
)
46 strncpy(w
->w_fileid
,"RIFF",4); /* chunk id 'RIFF' */
47 w
->w_chunksize
= x
->size
+ sizeof(t_wave
) -8; /* chunk size */
48 strncpy(w
->w_waveid
,"WAVE",4); /* wave chunk id 'WAVE' */
49 strncpy(w
->w_fmtid
,"fmt ",4); /* format chunk id 'fmt '*/
50 w
->w_fmtchunksize
= 16; /* format chunk size */
51 w
->w_fmttag
= 1; /* format tag, 1 for PCM */
52 w
->w_nchannels
= x
->x_channels
; /* number of channels */
53 w
->w_samplespersec
= 44100; /* sample rate in hz */
54 w
->w_navgbytespersec
= 44100*x
->x_channels
*2; /* average bytes per second */
55 w
->w_nblockalign
= 4; /* number of bytes per sample */
56 w
->w_nbitspersample
= 16; /* number of bits in a sample */
57 strncpy(w
->w_datachunkid
,"data",4); /* data chunk id 'data'*/
58 w
->w_datachunksize
= x
->size
; /* length of data chunk */
63 static void sfwrite_close(t_sfwrite
*x
)
67 sfwrite_wave_setup(x
,&w
);
68 lseek(x
->x_file
,0,SEEK_SET
);
69 write(x
->x_file
,&w
,sizeof(w
));
76 static void sfwrite_open(t_sfwrite
*x
,t_symbol
*filename
)
78 char fname
[MAXPDSTRING
];
80 if (filename
== &s_
) {
81 post("sfwrite: open without filename");
85 canvas_makefilename(glist_getcanvas(x
->x_glist
), filename
->s_name
,
89 x
->filename
= filename
;
90 post("sfwrite: filename = %s",x
->filename
->s_name
);
95 if ((x
->x_file
= open(fname
, O_RDWR
| O_CREAT
)) < 0)
97 if ((x
->x_file
= open(fname
,O_RDWR
| O_CREAT
,0664)) < 0)
100 error("can't create %s",fname
);
104 /* skip the header */
106 lseek(x
->x_file
,sizeof(t_wave
),SEEK_SET
);
112 static void sfwrite_block(t_sfwrite
*x
, t_floatarg f
)
118 static void sfwrite_float(t_sfwrite
*x
, t_floatarg f
)
122 post("sfwrite: start", f
);
126 post("sfwrite: stop", f
);
133 static short out
[4*64];
135 static t_int
*sfwrite_perform(t_int
*w
)
137 t_sfwrite
* x
= (t_sfwrite
*)(w
[1]);
139 int c
= x
->x_channels
;
143 int timebefore
,timeafter
;
146 for (i
=0;i
< c
;i
++) {
147 in
[i
] = (t_sample
*)(w
[2+i
]);
150 n
= num
= (int)(w
[2+c
]);
154 if (x
->rec
&& x
->x_file
) {
158 *tout
++ = (*(in
[i
])++)>>(fix1
-16);
162 timebefore
= sys_getrealtime();
163 if ((ret
=write(x
->x_file
,out
,sizeof(short)*num
*c
)) < (signed int)sizeof(short)*num
*c
) {
164 post("sfwrite: short write %d",ret
);
167 timeafter
= sys_getrealtime();
168 late
= timeafter
- timebefore
;
171 /* OK, we let only 10 ms block here */
172 if (late
> BLOCKTIME
&& x
->x_blockwarn
) {
173 post("sfwrite blocked %f ms",late
*1000);
175 if (x
->x_blocked
> x
->x_blockwarn
) {
177 post("maximum blockcount %d reached, recording stopped (set blockcount with \"block <num>\"",x
->x_blockwarn
);
181 x
->size
+=64*x
->x_channels
*sizeof(short) ;
189 static void sfwrite_dsp(t_sfwrite
*x
, t_signal
**sp
)
191 switch (x
->x_channels
) {
193 dsp_add(sfwrite_perform
, 3, x
, sp
[0]->s_vec
,
197 dsp_add(sfwrite_perform
, 4, x
, sp
[0]->s_vec
,
198 sp
[1]->s_vec
, sp
[0]->s_n
);
201 dsp_add(sfwrite_perform
, 6, x
, sp
[0]->s_vec
,
210 static void sfwrite_free(t_sfwrite
* x
)
216 static void *sfwrite_new(t_floatarg chan
)
218 t_sfwrite
*x
= (t_sfwrite
*)pd_new(sfwrite_class
);
221 if (c
<1 || c
> MAX_CHANS
) c
= 1;
223 x
->x_glist
= (t_glist
*) canvas_getcurrent();
231 inlet_new(&x
->x_obj
, &x
->x_obj
.ob_pd
, &s_signal
, &s_signal
);
238 void sfwrite_tilde_setup(void)
240 sfwrite_class
= class_new(gensym("sfwrite~"), (t_newmethod
)sfwrite_new
, (t_method
)sfwrite_free
,
241 sizeof(t_sfwrite
), 0,A_DEFFLOAT
,0);
242 class_addmethod(sfwrite_class
,nullfn
,gensym("signal"), 0);
243 class_addmethod(sfwrite_class
, (t_method
) sfwrite_dsp
, gensym("dsp"), 0);
244 class_addmethod(sfwrite_class
, (t_method
) sfwrite_open
, gensym("open"), A_SYMBOL
,A_NULL
);
245 class_addmethod(sfwrite_class
, (t_method
) sfwrite_close
, gensym("close"), 0);
246 class_addmethod(sfwrite_class
, (t_method
)sfwrite_block
,gensym("block"),A_DEFFLOAT
,0);
247 class_addfloat(sfwrite_class
, sfwrite_float
);