aboutsummaryrefslogtreecommitdiff
path: root/mp3write~.c
diff options
context:
space:
mode:
Diffstat (limited to 'mp3write~.c')
-rw-r--r--mp3write~.c329
1 files changed, 179 insertions, 150 deletions
diff --git a/mp3write~.c b/mp3write~.c
index 234110e..6cae3e9 100644
--- a/mp3write~.c
+++ b/mp3write~.c
@@ -58,8 +58,8 @@
#include "m_pd.h" /* standard pd stuff */
#define MY_MP3_MALLOC_IN_SIZE 65536
- /* max size taken from lame readme */
-#define MY_MP3_MALLOC_OUT_SIZE 1.25*MY_MP3_MALLOC_IN_SIZE+7200
+/* max size taken from lame readme */
+#define MY_MP3_MALLOC_OUT_SIZE 1.25*MY_MP3_MALLOC_IN_SIZE+7200
#define MAXDATARATE 320 /* maximum mp3 data rate is 320kbit/s */
#define STRBUF_SIZE 32
@@ -73,11 +73,11 @@ typedef struct _mp3write
{
t_object x_obj;
- /* LAME stuff */
+ /* LAME stuff */
int x_lame; /* info about encoder status */
int x_lamechunk; /* chunk size for LAME encoder */
- /* buffer stuff */
+ /* buffer stuff */
unsigned short x_inp; /* in position for buffer */
unsigned short x_outp; /* out position for buffer*/
short *x_mp3inbuf; /* data to be sent to LAME */
@@ -87,13 +87,13 @@ typedef struct _mp3write
int x_bytesbuffered; /* number of unprocessed bytes in buffer */
int x_start;
- /* mp3 format stuff */
+ /* mp3 format stuff */
int x_samplerate;
int x_bitrate; /* bitrate of mp3 stream */
int x_mp3mode; /* mode (mono, joint stereo, stereo, dual mono) */
int x_mp3quality; /* quality of encoding */
- /* recording stuff */
+ /* recording stuff */
int x_fd; /* file descriptor of the mp3 output */
int x_file_open_mode; /* file opening mode */
int x_byteswritten; /* number of bytes written */
@@ -106,7 +106,7 @@ typedef struct _mp3write
} t_mp3write;
- /* encode PCM data to mp3 stream */
+/* encode PCM data to mp3 stream */
static void mp3write_encode(t_mp3write *x)
{
unsigned short i, wp;
@@ -123,11 +123,11 @@ static void mp3write_encode(t_mp3write *x)
return;
}
- /* on start/reconnect set outpoint so that it won't interfere with inpoint */
+ /* on start/reconnect set outpoint so that it won't interfere with inpoint */
if(x->x_start == -1)
{
post("mp3write~: reseting buffer positions");
- /* we try to keep 2.5 times the data the encoder needs in the buffer */
+ /* we try to keep 2.5 times the data the encoder needs in the buffer */
if(x->x_inp > (2 * x->x_lamechunk))
{
x->x_outp = (short) x->x_inp - (2.5 * x->x_lamechunk);
@@ -142,10 +142,10 @@ static void mp3write_encode(t_mp3write *x)
i = MY_MP3_MALLOC_IN_SIZE - x->x_outp;
- /* read from buffer */
- if(x->x_lamechunk <= i)
+ /* read from buffer */
+ if(x->x_lamechunk <= i)
{
- /* enough data until end of buffer */
+ /* enough data until end of buffer */
for(n = 0; n < x->x_lamechunk; n++) /* fill encode buffer */
{
x->x_mp3inbuf[n] = x->x_buffer[n + x->x_outp];
@@ -166,14 +166,14 @@ static void mp3write_encode(t_mp3write *x)
x->x_outp = x->x_lamechunk - i;
}
- /* encode mp3 data */
+ /* encode mp3 data */
- x->x_mp3size = lame_encode_buffer_interleaved(x->lgfp, x->x_mp3inbuf,
- x->x_lamechunk/lame_get_num_channels(x->lgfp),
+ x->x_mp3size = lame_encode_buffer_interleaved(x->lgfp, x->x_mp3inbuf,
+ x->x_lamechunk/lame_get_num_channels(x->lgfp),
x->x_mp3outbuf, MY_MP3_MALLOC_OUT_SIZE);
// post( "mp3write~ : encoding returned %d frames", x->x_mp3size );
- /* check result */
+ /* check result */
if(x->x_mp3size<0)
{
lame_close( x->lgfp );
@@ -182,21 +182,22 @@ static void mp3write_encode(t_mp3write *x)
}
}
- /* store mp3 frames in the file */
+/* store mp3 frames in the file */
static void mp3write_writeframes(t_mp3write *x)
{
int err = -1; /* error return code */
- if ( x->x_fd < 0 ) {
- post( "mp3write~ : error : trying to write frames but no valid file is opened" );
- return;
+ if ( x->x_fd < 0 )
+ {
+ post( "mp3write~ : error : trying to write frames but no valid file is opened" );
+ return;
}
#ifdef _WIN32
err = _write(x->x_fd, x->x_mp3outbuf, x->x_mp3size);
#else
err = write(x->x_fd, x->x_mp3outbuf, x->x_mp3size);
-#endif
+#endif
if(err < 0)
{
@@ -211,17 +212,17 @@ static void mp3write_writeframes(t_mp3write *x)
close(x->x_fd);
#endif
x->x_fd = -1;
- }
- else
- {
+ }
+ else
+ {
x->x_byteswritten += err;
outlet_float( x->x_obj.ob_outlet, x->x_byteswritten );
- }
+ }
if((err > 0)&&(err != x->x_mp3size))error("mp3write~: %d bytes skipped", x->x_mp3size - err);
}
-
- /* buffer data as channel interleaved PCM */
+
+/* buffer data as channel interleaved PCM */
static t_int *mp3write_perform(t_int *w)
{
t_float *in1 = (t_float *)(w[1]); /* left audio inlet */
@@ -231,76 +232,94 @@ static t_int *mp3write_perform(t_int *w)
unsigned short i,wp;
float in;
- /* copy the data into the buffer */
+ /* copy the data into the buffer */
i = MY_MP3_MALLOC_IN_SIZE - x->x_inp; /* space left at the end of buffer */
-
+
n *= 2; /* two channels go into one buffer */
- if( n <= i )
+ if( n <= i )
{
/* the place between inp and MY_MP3_MALLOC_IN_SIZE */
/* is big enough to hold the data */
- for(wp = 0; wp < n; wp++)
+ for(wp = 0; wp < n; wp++)
+ {
+ if(wp%2)
+ {
+ in = *(in2++); /* right channel / inlet */
+ }
+ else
+ {
+ in = *(in1++); /* left channel / inlet */
+ }
+ if (in > 1.0)
+ {
+ in = 1.0;
+ }
+ if (in < -1.0)
{
- if(wp%2)
- {
- in = *(in2++); /* right channel / inlet */
- }
- else
- {
- in = *(in1++); /* left channel / inlet */
- }
- if (in > 1.0) { in = 1.0; }
- if (in < -1.0) { in = -1.0; }
- x->x_buffer[wp + x->x_inp] = (short) (32767.0 * in);
+ in = -1.0;
}
- x->x_inp += n; /* n more samples written to buffer */
- }
- else
+ x->x_buffer[wp + x->x_inp] = (short) (32767.0 * in);
+ }
+ x->x_inp += n; /* n more samples written to buffer */
+ }
+ else
{
- /* the place between inp and MY_MP3_MALLOC_IN_SIZE is not */
- /* big enough to hold the data */
- /* writing will take place in two turns, one from */
- /* x->x_inp -> MY_MP3_MALLOC_IN_SIZE, then from 0 on */
+ /* the place between inp and MY_MP3_MALLOC_IN_SIZE is not */
+ /* big enough to hold the data */
+ /* writing will take place in two turns, one from */
+ /* x->x_inp -> MY_MP3_MALLOC_IN_SIZE, then from 0 on */
- for(wp = 0; wp < i; wp++) /* fill up to end of buffer */
+ for(wp = 0; wp < i; wp++) /* fill up to end of buffer */
+ {
+ if(wp%2)
+ {
+ in = *(in2++);
+ }
+ else
+ {
+ in = *(in1++);
+ }
+ if (in > 1.0)
+ {
+ in = 1.0;
+ }
+ if (in < -1.0)
+ {
+ in = -1.0;
+ }
+ x->x_buffer[wp + x->x_inp] = (short) (32767.0 * in);
+ }
+ for(wp = i; wp < n; wp++) /* write rest at start of buffer */
+ {
+ if(wp%2)
+ {
+ in = *(in2++);
+ }
+ else
{
- if(wp%2)
- {
- in = *(in2++);
- }
- else
- {
- in = *(in1++);
- }
- if (in > 1.0) { in = 1.0; }
- if (in < -1.0) { in = -1.0; }
- x->x_buffer[wp + x->x_inp] = (short) (32767.0 * in);
+ in = *(in1++);
}
- for(wp = i; wp < n; wp++) /* write rest at start of buffer */
+ if (in > 1.0)
{
- if(wp%2)
- {
- in = *(in2++);
- }
- else
- {
- in = *(in1++);
- }
- if (in > 1.0) { in = 1.0; }
- if (in < -1.0) { in = -1.0; }
- x->x_buffer[wp - i] = (short) (32767.0 * in);
+ in = 1.0;
}
- x->x_inp = n - i; /* new writeposition in buffer */
+ if (in < -1.0)
+ {
+ in = -1.0;
+ }
+ x->x_buffer[wp - i] = (short) (32767.0 * in);
+ }
+ x->x_inp = n - i; /* new writeposition in buffer */
}
if((x->x_fd >= 0)&&(x->x_lame >= 0)&&(x->x_recflag))
- {
- /* count buffered samples when things are running */
+ {
+ /* count buffered samples when things are running */
x->x_bytesbuffered += n;
- /* encode and send to server */
+ /* encode and send to server */
if(x->x_bytesbuffered > x->x_lamechunk)
{
mp3write_encode(x); /* encode to mp3 */
@@ -320,10 +339,10 @@ static void mp3write_dsp(t_mp3write *x, t_signal **sp)
dsp_add(mp3write_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
}
- /* initialize the lame library */
+/* initialize the lame library */
static int mp3write_tilde_lame_init(t_mp3write *x)
{
- time_t now;
+ time_t now;
int ret;
x->lgfp = lame_init(); /* set default parameters for now */
@@ -342,11 +361,11 @@ static int mp3write_tilde_lame_init(t_mp3write *x)
}
#endif
{
- const char *lameVersion = get_lame_version();
- verbose(0, "mp3write~ : using lame version : %s", lameVersion );
+ const char *lameVersion = get_lame_version();
+ verbose(0, "mp3write~ : using lame version : %s", lameVersion );
}
- /* setting lame parameters */
+ /* setting lame parameters */
lame_set_num_channels( x->lgfp, 2);
lame_set_in_samplerate( x->lgfp, sys_getsr() );
lame_set_out_samplerate( x->lgfp, x->x_samplerate );
@@ -359,15 +378,18 @@ static int mp3write_tilde_lame_init(t_mp3write *x)
lame_set_disable_reservoir( x->lgfp, 0 );
lame_set_padding_type( x->lgfp, PAD_NO );
ret = lame_init_params( x->lgfp );
- if ( ret<0 ) {
- post( "mp3write~ : error : lame params initialization returned : %d", ret );
- return -1;
- } else {
- x->x_lame=1;
- /* magic formula copied from windows dll for MPEG-I */
- x->x_lamechunk = 2*1152;
-
- post( "mp3write~ : lame initialization done. (%d)", x->x_lame );
+ if ( ret<0 )
+ {
+ post( "mp3write~ : error : lame params initialization returned : %d", ret );
+ return -1;
+ }
+ else
+ {
+ x->x_lame=1;
+ /* magic formula copied from windows dll for MPEG-I */
+ x->x_lamechunk = 2*1152;
+
+ post( "mp3write~ : lame initialization done. (%d)", x->x_lame );
}
lame_init_bitstream( x->lgfp );
@@ -379,33 +401,36 @@ static int mp3write_tilde_lame_init(t_mp3write *x)
now=time(NULL);
sprintf( x->x_title, "Started at %s", ctime(&now) );
id3tag_set_title(x->lgfp, x->x_title );
-
+
return 0;
}
- /* open file and initialize lame */
+/* open file and initialize lame */
static void mp3write_open(t_mp3write *x, t_symbol *sfile)
{
- if ( mp3write_tilde_lame_init(x) < 0 ) {
- error( "mp3write~ : lame initialization failed ... check parameters.");
- return;
+ if ( mp3write_tilde_lame_init(x) < 0 )
+ {
+ error( "mp3write~ : lame initialization failed ... check parameters.");
+ return;
}
/* closing previous file descriptor */
- if ( x->x_fd > 0 ) {
+ if ( x->x_fd > 0 )
+ {
#ifdef _WIN32
- if(_close(x->x_fd) < 0 )
+ if(_close(x->x_fd) < 0 )
#else
- if(close(x->x_fd) < 0)
+ if(close(x->x_fd) < 0)
#endif
- {
- perror( "mp3write~ : closing file" );
- }
+ {
+ perror( "mp3write~ : closing file" );
+ }
}
- if ( x->x_recflag ) {
- x->x_recflag = 0;
+ if ( x->x_recflag )
+ {
+ x->x_recflag = 0;
}
#ifdef _WIN32
@@ -414,15 +439,15 @@ static void mp3write_open(t_mp3write *x, t_symbol *sfile)
if ( ( x->x_fd = open( sfile->s_name, x->x_file_open_mode, S_IRWXU|S_IRWXG|S_IRWXO ) ) < 0 )
#endif
{
- error( "mp3write~ : cannot open >%s<", sfile->s_name);
- x->x_fd=-1;
- return;
+ error( "mp3write~ : cannot open >%s<", sfile->s_name);
+ x->x_fd=-1;
+ return;
}
x->x_byteswritten = 0;
- post( "mp3write~ : opened >%s< fd=%d", sfile->s_name, x->x_fd);
-}
+ post( "mp3write~ : opened >%s< fd=%d", sfile->s_name, x->x_fd);
+}
- /* setting file write mode to append */
+/* setting file write mode to append */
static void mp3write_append(t_mp3write *x)
{
#ifdef _WIN32
@@ -433,7 +458,7 @@ static void mp3write_append(t_mp3write *x)
if(x->x_fd>=0)post("mp3write~ : mode set to append : open a new file to make changes take effect! ");
}
- /* setting file write mode to truncate */
+/* setting file write mode to truncate */
static void mp3write_truncate(t_mp3write *x)
{
#ifdef _WIN32
@@ -444,9 +469,9 @@ static void mp3write_truncate(t_mp3write *x)
if(x->x_fd>=0)post("mp3write~ : mode set to truncate : open a new file to make changes take effect! ");
}
- /* settings for mp3 encoding */
+/* settings for mp3 encoding */
static void mp3write_mpeg(t_mp3write *x, t_floatarg fsamplerate, t_floatarg fbitrate,
- t_floatarg fmode, t_floatarg fquality)
+ t_floatarg fmode, t_floatarg fquality)
{
x->x_samplerate = fsamplerate;
if(fbitrate > MAXDATARATE)
@@ -457,11 +482,11 @@ static void mp3write_mpeg(t_mp3write *x, t_floatarg fsamplerate, t_floatarg fbit
x->x_mp3mode = fmode;
x->x_mp3quality = fquality;
post("mp3write~: setting mp3 stream to %dHz, %dkbit/s, mode %d, quality %d",
- x->x_samplerate, x->x_bitrate, x->x_mp3mode, x->x_mp3quality);
+ x->x_samplerate, x->x_bitrate, x->x_mp3mode, x->x_mp3quality);
if(x->x_fd>=0)post("mp3write~ : restart recording to make changes take effect! ");
}
- /* print settings */
+/* print settings */
static void mp3write_print(t_mp3write *x)
{
const char * buf = 0;
@@ -471,18 +496,18 @@ static void mp3write_print(t_mp3write *x)
" bitrate: %d kbit/s", x->x_samplerate, x->x_bitrate);
switch(x->x_mp3mode)
{
- case 0 :
- buf = "stereo";
- break;
- case 1 :
- buf = "joint stereo";
- break;
- case 2 :
- buf = "dual channel";
- break;
- case 3 :
- buf = "mono";
- break;
+ case 0 :
+ buf = "stereo";
+ break;
+ case 1 :
+ buf = "joint stereo";
+ break;
+ case 2 :
+ buf = "dual channel";
+ break;
+ case 3 :
+ buf = "mono";
+ break;
}
post(" mode: %s\n"
" quality: %d", buf, x->x_mp3quality);
@@ -497,51 +522,55 @@ static void mp3write_print(t_mp3write *x)
}
}
- /* start recording */
+/* start recording */
static void mp3write_start(t_mp3write *x)
{
- if ( x->x_fd < 0 ) {
- post("mp3write~: start received but no file has been set ... ignored.");
- return;
+ if ( x->x_fd < 0 )
+ {
+ post("mp3write~: start received but no file has been set ... ignored.");
+ return;
}
-
- if ( x->x_recflag == 1 ) {
- post("mp3write~: start received but recording is started ... ignored.");
- return;
+
+ if ( x->x_recflag == 1 )
+ {
+ post("mp3write~: start received but recording is started ... ignored.");
+ return;
}
-
+
x->x_recflag = 1;
post("mp3write~: start recording");
}
- /* stop recording */
+/* stop recording */
static void mp3write_stop(t_mp3write *x)
{
int err = -1;
- if ( x->x_fd < 0 ) {
- post("mp3write~: stop received but no file has been set ... ignored.");
- return;
+ if ( x->x_fd < 0 )
+ {
+ post("mp3write~: stop received but no file has been set ... ignored.");
+ return;
}
-
- if ( x->x_recflag == 0 ) {
- post("mp3write~: stop received but recording is stopped ... ignored.");
- return;
+
+ if ( x->x_recflag == 0 )
+ {
+ post("mp3write~: stop received but recording is stopped ... ignored.");
+ return;
}
- /* first stop recording / buffering and so on, than do the rest */
+ /* first stop recording / buffering and so on, than do the rest */
x->x_recflag = 0;
/* flushing remaining frames and tag */
- x->x_mp3size = lame_encode_flush( x->lgfp, x->x_mp3outbuf, MY_MP3_MALLOC_OUT_SIZE );
-
+ x->x_mp3size = lame_encode_flush( x->lgfp, x->x_mp3outbuf, MY_MP3_MALLOC_OUT_SIZE );
+
mp3write_writeframes(x); /* write mp3 to file */
x->x_recflag = 0;
post("mp3write~: stop recording, flushed %d bytes", x->x_mp3size);
}
- /* clean up */
-static void mp3write_free(t_mp3write *x)
+/* clean up */
+static void mp3write_free(t_mp3write *x)
{
if(x->x_lame >= 0)
lame_close( x->lgfp );
@@ -595,7 +624,7 @@ void mp3write_tilde_setup(void)
{
verbose(0, mp3write_version);
mp3write_class = class_new(gensym("mp3write~"), (t_newmethod)mp3write_new, (t_method)mp3write_free,
- sizeof(t_mp3write), 0, 0);
+ sizeof(t_mp3write), 0, 0);
CLASS_MAINSIGNALIN(mp3write_class, t_mp3write, x_f );
class_addmethod(mp3write_class, (t_method)mp3write_dsp, gensym("dsp"), 0);
class_addmethod(mp3write_class, (t_method)mp3write_open, gensym("open"), A_SYMBOL, 0);