aboutsummaryrefslogtreecommitdiff
path: root/mp3live~
diff options
context:
space:
mode:
Diffstat (limited to 'mp3live~')
-rw-r--r--mp3live~/INSTALL21
-rw-r--r--mp3live~/interface.h32
-rw-r--r--mp3live~/mp3fileout~.c558
-rw-r--r--mp3live~/mp3live~-help.pd118
-rw-r--r--mp3live~/mp3streamin~.c671
-rw-r--r--mp3live~/mp3streamout~.c617
-rw-r--r--mp3live~/mpglib.h65
-rw-r--r--mp3live~/test-streaming-mp3.pd96
8 files changed, 0 insertions, 2178 deletions
diff --git a/mp3live~/INSTALL b/mp3live~/INSTALL
deleted file mode 100644
index 63db4c7..0000000
--- a/mp3live~/INSTALL
+++ /dev/null
@@ -1,21 +0,0 @@
-You need to get lame > v3.90 installed first.
-libmp3lame.so is searched in /usr/local/lib
-( no time to write configure scripts ).
-if it's installed elsewhere, change the Makefile,
-you won't die from that.
-
-untar in /my/pd/dir/externs
-
-cd /my/pd/dir/externs/mp3live~
-
-make clean
-
-make
-
-make install
-
-open help-mp3live~.pd
-
-Thanx for getting here.
-
-Yves/
diff --git a/mp3live~/interface.h b/mp3live~/interface.h
deleted file mode 100644
index de3136a..0000000
--- a/mp3live~/interface.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-** Copyright (C) 2000 Albert L. Faber
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifndef INTERFACE_H_INCLUDED
-#define INTERFACE_H_INCLUDED
-
-// #include "common.h"
-#include "interface.h"
-
-BOOL InitMP3(PMPSTR mp);
-int decodeMP3(PMPSTR mp,unsigned char *inmemory,int inmemsize,char *outmemory,int outmemsize,int *done);
-void ExitMP3(PMPSTR mp);
-
-/* added remove_buf to support mpglib seeking */
-void remove_buf(PMPSTR mp);
-
-#endif
diff --git a/mp3live~/mp3fileout~.c b/mp3live~/mp3fileout~.c
deleted file mode 100644
index bd2d431..0000000
--- a/mp3live~/mp3fileout~.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/* ------------------------ mp3fileout~ --------------------------------------- */
-/* */
-/* Tilde object to send an mp3 file to a peer using mp3streamin~ */
-/* Written by Yves Degoyon (ydegoyon@free.fr). */
-/* Tarballs and updates @ http://ydegoyon.free.fr */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* See file LICENSE for further informations on licensing terms. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* Uses the LAME MPEG 1 Layer 3 encoding library (lame_enc.dll) which can */
-/* be found at http://www.cdex.n3.net. */
-/* */
-/* "See mass murder on a scale you've never seen" */
-/* "And all the one who tried hard to succeed" */
-/* You know who, don't you ??? */
-/* ---------------------------------------------------------------------------- */
-
-
-#include <m_pd.h>
-#include <m_imp.h>
-#include <g_canvas.h>
-
-#include <sys/types.h>
-#include <string.h>
-#ifdef _WIN32
-#include <winsock.h>
-#include <io.h>
-#include <fcntl.h>
-#else
-#include <sys/socket.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#define SOCKET_ERROR -1
-#endif /* _WIN32 */
-
-#if defined(__APPLE__) || defined(_WIN32)
-#define MSG_NOSIGNAL 0
-#endif
-
-
-#include "mpg123.h" /* mpg123 decoding library from lame 3.92 */
-#include "mpglib.h" /* mpglib decoding library from lame 3.92 */
-#include "interface.h" /* mpglib decoding library from lame 3.92 */
-
-#define INPUT_BUFFER_SIZE 32768
-#define OUTPUT_BUFFER_SIZE 32768
-#define MAX_FRAME_SIZE 1152
-
-/* useful debugging functions from mpglib */
-extern int decode_header( struct frame* fr, unsigned long newhead );
-extern void print_header_compact( struct frame* fr );
-extern int head_check( unsigned long head, int check_layer );
-
-/* time-out used for select() call */
-static struct timeval ztout;
-
-static char *mp3fileout_version = "mp3fileout~: mp3 file streamer version 0.2, written by ydegoyon@free.fr";
-
-extern void sys_sockerror(char *s);
-
-void mp3fileout_closesocket(int fd)
-{
-#ifdef UNIX
- if ( close(fd) < 0 )
- {
- perror( "close" );
- }
- else
- {
- post( "mp3fileout~ : closed socket : %d", fd );
- }
-#endif
-#ifdef NT
- closesocket(fd);
-#else
- sys_rmpollfn(fd);
-#endif
-}
-
-/* ------------------------ mp3fileout~ ----------------------------- */
-
-static t_class *mp3fileout_class;
-
-typedef struct _mp3fileout
-{
- t_object x_obj;
- t_int x_socket;
- t_int x_fd; /* file descriptor for the mp3 file */
- t_int x_eof; /* end of file is reached */
- t_int x_emit; /* indicates the ability to emit */
- t_int x_nbwaitloops;/* synchronization cycles count */
- t_int x_blocksize; /* actual blocksize */
-
- void *x_inbuffer; /* accumulation buffer for read mp3 frames */
- t_int x_inwriteposition;
- t_int x_inbuffersize;
- t_int x_framesize;
- t_int x_offset; /* offset used for decoding */
- t_int x_nbloops; /* number of perform loops */
-
- void *x_outbuffer; /* buffer to be emitted */
- t_int x_outframes; /* number of frames emitted */
- t_int x_outbuffersize;
- t_int x_outavable; /* number of available bytes to emit */
-
- t_canvas *x_canvas;
-
- t_outlet *x_connected; /* indicates state of the connection */
- t_outlet *x_endreached;/* indicates the end of file */
- t_outlet *x_frames; /* indicates the number of frames emitted */
-
-} t_mp3fileout;
-
-static int mp3fileout_search_header(t_mp3fileout *x)
-{
- t_int i;
- t_int length = 0;
- struct frame hframe;
- unsigned long cheader;
- t_int ret = sizeof( unsigned long);
- t_int foffset = 0;
- unsigned int a,b,c,d;
- unsigned char buf[sizeof(unsigned long)];
- t_float nbsamplesframe = 0;
-
- while( ret>0 )
- {
- ret = read( x->x_fd, (void *)buf, sizeof( unsigned long ) );
-
- foffset+=ret;
-
- if ( ret>0 )
- {
- /* check for a valid header */
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- cheader = 0;
- cheader = a;
- cheader <<= 8;
- cheader |= b;
- cheader <<= 8;
- cheader |= c;
- cheader <<= 8;
- cheader |= d;
- if ( head_check( cheader, 0 ) )
- {
- decode_header( &hframe, cheader );
- // print_header_compact( &hframe );
- x->x_framesize = hframe.framesize;
- nbsamplesframe = ( hframe.mpeg25 ? 576 : 1152 );
- x->x_nbwaitloops = (int)(nbsamplesframe/x->x_blocksize);
- if ( x->x_nbwaitloops == 0 ) x->x_nbwaitloops = 1;
- // post ( "mp3fileout~ : will wait %d loops", x->x_nbwaitloops );
-
- // rewind file to the start of the frame
- if ( lseek( x->x_fd, -sizeof(unsigned long), SEEK_CUR ) < 0 )
- {
- post( "mp3fileout~ : could not rewind file." );
- }
- if ( x->x_outframes == 0 )
- {
- post( "mp3fileout~ : found firstframe @ %d", foffset );
- }
- break;
- }
- // post( "mp3fileout~ : read %d bytes.", ret );
- }
- else
- {
- if ( ret < 0 )
- {
- post( "mp3fileout~ : error encountered ( ret=%d )...file reading done.", ret );
- perror( "read" );
- x->x_eof = 1;
- }
- else
- {
- post( "mp3fileout~ : file reading done.", ret );
- x->x_eof = 1;
- outlet_bang( x->x_endreached );
- }
- return -1;
- }
-
- }
-
- return x->x_framesize;
-}
-
-static int mp3fileout_read_frame(t_mp3fileout *x)
-{
- int size, ret;
-
- if ( x->x_fd > 0 && !x->x_eof)
- {
- if ( ( size = mp3fileout_search_header( x ) ) > 0 )
- {
- if ( size+sizeof(unsigned long) > INPUT_BUFFER_SIZE )
- {
- post( "mp3fileout~ : cannot read frame : size too big : %d", size );
- return -1;
- }
- // post( "mp3fileout~ : reading a frame : size : %d", size );
- ret = read( x->x_fd, x->x_inbuffer, size+sizeof(unsigned long) );
-
- if ( ret>0 )
- {
- memcpy( x->x_outbuffer, x->x_inbuffer, ret );
- x->x_outavable += ret;
- return ret;
- }
- else
- {
- return -1;
- }
- }
- else
- {
- return -1;
- }
- }
- else
- {
- return -1;
- }
-}
-
-static int mp3fileout_send_frame(t_mp3fileout *x)
-{
- int ret=0;
-
- if ( x->x_socket > 0 && x->x_emit )
- {
- if ( ( ret = send( x->x_socket, x->x_outbuffer, x->x_outavable, MSG_NOSIGNAL ) ) < 0 )
- {
- post( "mp3fileout~ : connection lost." );
- perror( "send" );
- x->x_socket = -1;
- x->x_emit = 0;
- return -1;
- }
- else
- {
- memcpy( x->x_outbuffer, x->x_outbuffer+ret, x->x_outbuffersize-ret );
- x->x_outavable -= ret;
- x->x_outframes++;
- outlet_float( x->x_frames, x->x_outframes );
- // post( "mp3fileout~ : sent %d bytes, x->x_outavable : %d", ret, x->x_outavable );
- }
-
- }
- else
- {
- // artificially empty buffer
- x->x_outavable = 0;
- }
- return ret;
-}
-
-static void mp3fileout_free(t_mp3fileout *x)
-{
- if (x->x_socket > 0) {
- post( "mp3fileout~ : closing socket" );
- mp3fileout_closesocket(x->x_socket);
- x->x_socket = -1;
- }
- if ( x->x_fd > 0 )
- {
- if ( close( x->x_fd ) < 0 )
- {
- post( "mp3fileout~ : could not close file." );
- perror( "close" );
- }
- }
- if ( x->x_inbuffer ) freebytes( x->x_inbuffer, x->x_inbuffersize );
-}
-
-static t_int *mp3fileout_perform(t_int *w)
-{
- t_mp3fileout *x = (t_mp3fileout*) (w[1]);
- int ret;
- int i = 0;
-
- x->x_blocksize = (t_int)(w[2]);
- // check new incoming data
- if ( x->x_socket > 0 )
- {
- if ( x->x_nbloops % x->x_nbwaitloops == 0 )
- {
- /* read a frame in the file */
- if ( mp3fileout_read_frame(x) > 0 )
- {
- /* send the frame to the peer */
- mp3fileout_send_frame(x);
- }
- }
- x->x_nbloops = ( x->x_nbloops+1 ) % x->x_nbwaitloops;
- }
- return (w+3);
-}
-
-static void mp3fileout_dsp(t_mp3fileout *x, t_signal **sp)
-{
- dsp_add(mp3fileout_perform, 2, x, sp[0]->s_n);
-}
-
- /* start streaming */
-static void mp3fileout_start(t_mp3fileout *x)
-{
- x->x_emit = 1;
- if ( x->x_fd > 0 )
- {
- // reset file pointer
- if ( lseek( x->x_fd, 0, SEEK_SET ) < 0 )
- {
- post ( "mp3fileout~ : could not reset file pointer.");
- x->x_eof = 1;
- return;
- }
- x->x_eof = 0;
- x->x_outframes = 0;
- outlet_float( x->x_frames, x->x_outframes );
- }
-}
-
- /* resume file reading */
-static void mp3fileout_resume(t_mp3fileout *x)
-{
- x->x_emit = 1;
-}
-
- /* seek in file */
-static void mp3fileout_seek(t_mp3fileout *x, t_floatarg foffset)
-{
- if ( foffset < 0 )
- {
- post( "mp3fileout~ : wrong offset.");
- return;
- }
- if ( x->x_fd > 0 )
- {
- // reset file pointer
- if ( lseek( x->x_fd, (int)foffset, SEEK_SET ) < 0 )
- {
- post ( "mp3fileout~ : could not reset file pointer.");
- x->x_eof = 1;
- return;
- }
- x->x_eof = 0;
- }
-}
-
- /* stop streaming */
-static void mp3fileout_stop(t_mp3fileout *x)
-{
- x->x_emit = 0;
-}
-
- /* open mp3 file */
-static void mp3fileout_open(t_mp3fileout *x, t_symbol *filename)
-{
- // first close previous file
- if ( x->x_fd > 0 )
- {
- if ( close( x->x_fd ) < 0 )
- {
- post( "mp3fileout~ : could not close file." );
- perror( "close" );
- }
- x->x_outframes = 0;
- outlet_float( x->x_frames, x->x_outframes );
- }
-
- if ( ( x->x_fd = open( filename->s_name, O_RDONLY ) ) < 0 )
- {
- post( "mp3fileout~ : could not open file : %s", filename->s_name );
- perror( "open" );
- x->x_eof = 1;
- }
- else
- {
- x->x_eof = 0;
- post( "mp3fileout~ : opened file : %s ( fd = %d )", filename->s_name, x->x_fd );
- }
-}
-
- /* connect to the peer */
-static void mp3fileout_connect(t_mp3fileout *x, t_symbol *hostname, t_floatarg fportno)
-{
- struct sockaddr_in csocket;
- struct hostent *hp;
- int portno = fportno; /* get port from message box */
-
- /* variables used for communication with the peer */
- unsigned int len;
- int sockfd;
-
-#ifndef UNIX
- unsigned int ret;
-#else
- int ret;
-#endif
-
- if (x->x_socket >= 0)
- {
- error("mp3fileout~: already connected");
- return;
- }
-
- sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sockfd < 0)
- {
- error("mp3fileout~: internal error while attempting to open socket");
- return;
- }
-
- /* connect socket using hostname provided in command line */
- csocket.sin_family = AF_INET;
- hp = gethostbyname(hostname->s_name);
- if (hp == 0)
- {
- post("mp3fileout~: bad host?");
-#ifndef UNIX
- closesocket(sockfd);
-#else
- close(sockfd);
-#endif
- return;
- }
- memcpy((char *)&csocket.sin_addr, (char *)hp->h_addr, hp->h_length);
-
- /* assign client port number */
- csocket.sin_port = htons((unsigned short)portno);
-
- /* try to connect. */
- post("mp3fileout~: connecting to port %d", portno);
- if (connect(sockfd, (struct sockaddr *) &csocket, sizeof (csocket)) < 0)
- {
- error("mp3fileout~: connection failed!\n");
-#ifndef UNIX
- closesocket(sockfd);
-#else
- close(sockfd);
-#endif
- return;
- }
-
- x->x_socket = sockfd;
- x->x_outframes = 0;
- outlet_float( x->x_frames, x->x_outframes );
- outlet_float( x->x_connected, 1 );
- post( "mp3fileout~ : connected to peer" );
-
-}
-
- /* close connection to the peer */
-static void mp3fileout_disconnect(t_mp3fileout *x)
-{
-
- int err = -1;
- if(x->x_socket >= 0) /* close socket */
- {
-#ifndef UNIX
- closesocket(x->x_socket);
-#else
- close(x->x_socket);
-#endif
- x->x_socket = -1;
- outlet_float( x->x_connected, 0 );
- x->x_outframes = 0;
- outlet_float( x->x_frames, x->x_outframes );
- post("mp3fileout~: connection closed");
- }
-}
-
-static void *mp3fileout_new(void)
-{
- t_mp3fileout *x;
- int i;
-
- x = (t_mp3fileout *)pd_new(mp3fileout_class);
- x->x_connected = outlet_new( &x->x_obj, &s_float );
- x->x_frames = outlet_new( &x->x_obj, &s_float );
- x->x_endreached = outlet_new( &x->x_obj, &s_bang );
-
- x->x_socket = -1;
- x->x_fd = -1;
- x->x_eof = 0;
- x->x_canvas = canvas_getcurrent();
-
- x->x_offset = 0;
- x->x_inbuffersize = INPUT_BUFFER_SIZE;
- x->x_inbuffer = (char*) getbytes( x->x_inbuffersize );
- if ( !x->x_inbuffer )
- {
- post( "mp3fileout~ : could not allocate buffers." );
- return NULL;
- }
- memset( x->x_inbuffer, 0x0, INPUT_BUFFER_SIZE );
-
- x->x_outbuffersize = OUTPUT_BUFFER_SIZE;
- x->x_outbuffer = (char*) getbytes( x->x_outbuffersize );
- if ( !x->x_outbuffer )
- {
- post( "mp3fileout~ : could not allocate buffers." );
- return NULL;
- }
- memset( x->x_outbuffer, 0x0, OUTPUT_BUFFER_SIZE );
- x->x_outavable = 0;
-
- x->x_inwriteposition = 0;
- x->x_nbloops = 0;
- x->x_nbwaitloops = 1;
-
- return (x);
-}
-
-void mp3fileout_tilde_setup(void)
-{
- post( mp3fileout_version );
- mp3fileout_class = class_new(gensym("mp3fileout~"),
- (t_newmethod) mp3fileout_new, (t_method) mp3fileout_free,
- sizeof(t_mp3fileout), 0, A_NULL);
-
- class_addmethod(mp3fileout_class, nullfn, gensym("signal"), 0);
- class_addmethod(mp3fileout_class, (t_method) mp3fileout_dsp, gensym("dsp"), 0);
- class_addmethod(mp3fileout_class, (t_method)mp3fileout_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(mp3fileout_class, (t_method)mp3fileout_open, gensym("open"), A_SYMBOL, 0);
- class_addmethod(mp3fileout_class, (t_method)mp3fileout_disconnect, gensym("disconnect"), 0);
- class_addmethod(mp3fileout_class, (t_method)mp3fileout_start, gensym("start"), 0);
- class_addmethod(mp3fileout_class, (t_method)mp3fileout_resume, gensym("resume"), 0);
- class_addmethod(mp3fileout_class, (t_method)mp3fileout_seek, gensym("seek"), A_DEFFLOAT, 0);
- class_addmethod(mp3fileout_class, (t_method)mp3fileout_stop, gensym("stop"), 0);
-}
diff --git a/mp3live~/mp3live~-help.pd b/mp3live~/mp3live~-help.pd
deleted file mode 100644
index ac68464..0000000
--- a/mp3live~/mp3live~-help.pd
+++ /dev/null
@@ -1,118 +0,0 @@
-#N canvas 11 -3 941 684 10;
-#X msg 35 594 \; pd dsp 1;
-#X text 432 123 <-- settings for mp3 stream;
-#X text 492 177 1 = joint stereo (default);
-#X text 456 165 mode: 0 = stereo;
-#X text 492 189 2 = dual channel;
-#X msg 101 594 \; pd dsp 0;
-#X obj 551 317 dac~;
-#X msg 368 80 disconnect;
-#X floatatom 221 227 5 0 0;
-#X obj 221 199 mp3streamout~;
-#X msg 367 54 connect localhost 5000;
-#X msg 767 69 bang;
-#X obj 767 89 openpanel;
-#X obj 766 186 soundfiler;
-#X floatatom 767 210 10 0 0;
-#X obj 767 111 t s b;
-#X obj 767 148 pack s s;
-#X msg 766 169 read -resize \$1 \$2;
-#X obj 803 111 float \$0;
-#X text 755 50 Step 1 : Load a sound file;
-#X obj 767 128 route float;
-#X obj 123 149 tabplay~ \$0-sample;
-#X msg 123 120 bang;
-#X obj 114 627 table \$0-sample;
-#X obj 821 148 makefilename %d-sample;
-#X text 371 34 Step 2 : connect the streamer;
-#X text 8 100 Step 3 : emit a sound through the streamer;
-#X obj 234 276 env~;
-#X obj 67 310 timer;
-#X obj 207 276 > 0;
-#X obj 159 276 route 1;
-#X obj 122 276 t b f;
-#X floatatom 121 340 5 0 0;
-#X obj 80 276 spigot;
-#X msg 102 256 0;
-#X msg 130 256 1;
-#X text 453 135 (bitrate \, mode \, quality);
-#X text 453 227 Note : resampling is not supported for now;
-#X text 454 238 Note : see the README for allowed bitrate;
-#X text 30 9 mp3live~ : mp3streamout~ / mp3streamin~;
-#X text 30 20 peer-to-peer mp3 streaming \, written by ydegoyon@free.fr
-;
-#X msg 342 147 mpeg 32 2 9;
-#X text 492 202 3 = mono ( not supported );
-#X text 455 153 bitrate: bitrate of stream \, def. 128kbit/s;
-#X text 452 215 quality: 5 = high \, 9 = low;
-#X text 85 360 streamer latency (ms);
-#X obj 35 573 loadbang;
-#X msg 343 123 mpeg 128 0 5;
-#X obj 536 270 mp3streamin~ 5000 1;
-#X symbolatom 639 300 10 0 0;
-#X text 622 316 Incomer's address;
-#X floatatom 229 496 5 0 0;
-#X floatatom 327 498 5 0 0;
-#X text 282 366 Step 3 bis : emit a file through the streamer;
-#X msg 298 386 bang;
-#X msg 299 423 open \$1;
-#X msg 393 410 disconnect;
-#X msg 393 391 connect localhost 5000;
-#X msg 393 429 start;
-#X msg 438 430 stop;
-#X obj 298 406 openpanel;
-#X text 292 522 Number of frames emitted;
-#X text 160 515 Connection state;
-#X text 31 36 Warning : mp3fileout~ will not read ANY mp3 file \,;
-#X text 30 46 but \, at least \, those produced with mp3write~.;
-#X msg 474 430 resume;
-#X msg 524 429 seek 10000;
-#X text 391 503 A bang is emitted at the end of the file;
-#X obj 301 454 mp3fileout~;
-#X obj 389 485 print thisistheend;
-#X connect 7 0 9 0;
-#X connect 9 0 8 0;
-#X connect 10 0 9 0;
-#X connect 11 0 12 0;
-#X connect 12 0 15 0;
-#X connect 13 0 14 0;
-#X connect 15 0 16 0;
-#X connect 15 1 18 0;
-#X connect 16 0 17 0;
-#X connect 17 0 13 0;
-#X connect 18 0 20 0;
-#X connect 20 0 24 0;
-#X connect 21 0 9 0;
-#X connect 21 0 9 1;
-#X connect 22 0 21 0;
-#X connect 22 0 28 0;
-#X connect 22 0 35 0;
-#X connect 24 0 16 1;
-#X connect 27 0 29 0;
-#X connect 28 0 32 0;
-#X connect 29 0 30 0;
-#X connect 30 0 31 0;
-#X connect 31 0 33 0;
-#X connect 32 0 34 0;
-#X connect 33 0 28 1;
-#X connect 34 0 33 1;
-#X connect 35 0 33 1;
-#X connect 41 0 9 0;
-#X connect 46 0 0 0;
-#X connect 47 0 9 0;
-#X connect 48 0 6 0;
-#X connect 48 0 27 0;
-#X connect 48 1 6 1;
-#X connect 48 2 49 0;
-#X connect 54 0 60 0;
-#X connect 55 0 68 0;
-#X connect 56 0 68 0;
-#X connect 57 0 68 0;
-#X connect 58 0 68 0;
-#X connect 59 0 68 0;
-#X connect 60 0 55 0;
-#X connect 65 0 68 0;
-#X connect 66 0 68 0;
-#X connect 68 0 51 0;
-#X connect 68 1 52 0;
-#X connect 68 2 69 0;
diff --git a/mp3live~/mp3streamin~.c b/mp3live~/mp3streamin~.c
deleted file mode 100644
index b01a576..0000000
--- a/mp3live~/mp3streamin~.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/* ------------------------ mp3streamin~ -------------------------------------- */
-/* */
-/* Tilde object to receive an mp3-stream sent by a peer using mp3streamout~. */
-/* Written by Yves Degoyon (ydegoyon@free.fr). */
-/* Tarballs and updates @ http://ydegoyon.free.fr */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* See file LICENSE for further informations on licensing terms. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* Uses the LAME MPEG 1 Layer 3 encoding library (lame_enc.dll) which can */
-/* be found at http://www.cdex.n3.net. */
-/* */
-/* "Repackage sex, your interests." */
-/* "Somehow, maintain the interest." */
-/* Gang Of Four -- Natural's Not In It */
-/* ---------------------------------------------------------------------------- */
-
-
-#include <m_pd.h>
-#include <m_imp.h>
-#include <g_canvas.h>
-
-#if PD_MINOR_VERSION >=37
-#include "s_stuff.h"
-#endif
-
-#include <sys/types.h>
-#include <string.h>
-#ifdef _WIN32
-#include <io.h>
-#include <winsock.h>
-#else
-#include <sys/socket.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#define SOCKET_ERROR -1
-#endif /* _WIN32 */
-
-#if defined(__APPLE__) || defined(_WIN32)
-#define MSG_NOSIGNAL 0
-#define SOL_TCP IPPROTO_TCP
-#endif
-
-#include "mpg123.h" /* mpg123 decoding library from lame 3.92 */
-#include "mpglib.h" /* mpglib decoding library from lame 3.92 */
-#include "interface.h" /* mpglib decoding library from lame 3.92 */
-
-#define MIN_AUDIO_INPUT 8064 // we must a least have 8 chunks to play a correct sound
-#define INPUT_BUFFER_SIZE MIN_AUDIO_INPUT
-#define OUTPUT_BUFFER_SIZE 131072 /* 128k*/
-#define LAME_AUDIO_CHUNK_SIZE 1152
-#define BARHEIGHT 10
-#define MAX_DECODERS 10
-
-/* useful debugging functions from mpglib */
-extern int decode_header( struct frame* fr, unsigned long newhead );
-extern void print_header_compact( struct frame* fr );
-extern int head_check( unsigned long head, int check_layer );
-
-/* time-out used for select() call */
-static struct timeval ztout;
-
-static char *mp3streamin_version = "mp3streamin~: mp3 peer-to-peer streamer version 0.3, written by ydegoyon@free.fr";
-
-extern void sys_sockerror(char *s);
-
-void mp3streamin_closesocket(int fd)
-{
-#ifdef UNIX
- if ( close(fd) < 0 )
- {
- perror( "close" );
- }
- else
- {
- post( "mp3streamin~ : closed socket : %d", fd );
- }
-#endif
-#ifdef NT
- closesocket(fd);
-#endif
- sys_rmpollfn(fd);
-}
-
-int setsocketoptions(int sockfd)
-{
- int sockopt = 1;
- if (setsockopt(sockfd, SOL_TCP, TCP_NODELAY, (const char*) &sockopt, sizeof(int)) < 0)
- {
- post("mp3streamin~ : setsockopt TCP_NODELAY failed");
- perror( "setsockopt" );
- return -1;
- }
- else
- {
- post("mp3streamin~ : TCP_NODELAY set");
- }
-
-#ifdef UNIX
- sockopt = 1;
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int)) < 0)
- {
- post("mp3streamin~ : setsockopt SO_REUSEADDR failed");
- perror( "setsockopt" );
- return -1;
- }
- else
- {
- post("mp3streamin~ : setsockopt SO_REUSEADDR done.");
- }
-#endif
- return 0;
-}
-
-
-/* ------------------------ mp3streamin~ ----------------------------- */
-
-static t_class *mp3streamin_class;
-
-typedef struct _mp3streamin
-{
- t_object x_obj;
- t_int x_instance;
- t_int x_socket;
- t_int x_shutdown;
- t_outlet *x_connectionip;
- t_int x_serversocket;
- t_int x_inpackets; /* number of packets received */
- t_int x_dpacket; /* displayed packet in status bar */
- t_int x_packetsize; /* size of the packets */
- t_int x_pblocks; /* processed blocks */
- t_int x_graphic; /* indicates if we show a graphic bar */
-
- void *x_inbuffer; /* accumulation buffer for incoming mp3 frames */
- t_int x_inwriteposition;
- t_int x_inbuffersize;
-
- t_float *x_outbuffer; /* buffer to store audio decoded data */
- t_int x_outwriteposition;
- t_int x_outreadposition;
- t_int x_outunread;
- t_int x_outbuffersize;
-
- t_canvas *x_canvas;
-
- t_int x_stream; /* indicates if a stream is connected ( meaning correct input flow ) */
- t_int x_newstream; /* at first, the stream must provide enough data to start */
- t_int x_bitrateindex; /* remember the bitrate index */
-
-} t_mp3streamin;
-
-/* too bad, this needs to be static,
- handling an array to enable several decoders in pd */
-static MPSTR mp[MAX_DECODERS]; /* decoder buffer */
-int nbinstances = 0;
-
-void mp3streamin_tilde_mpglib_init(t_mp3streamin *x)
-{
- int ret;
-
- InitMP3(&mp[x->x_instance]);
-}
-
-static int mp3streamin_decode_input(t_mp3streamin *x)
-{
- int i;
- int alength = 0;
- struct frame hframe;
- unsigned int a,b,c,d;
- unsigned long cheader;
- static char out[8192];
- signed short int *p = (signed short int *) out;
- int pbytes;
- int ret;
-
- if ( !x->x_shutdown )
- {
- /* decode first 4 bytes as the header */
- a = *((unsigned char*)x->x_inbuffer);
- b = *((unsigned char*)x->x_inbuffer+1);
- c = *((unsigned char*)x->x_inbuffer+2);
- d = *((unsigned char*)x->x_inbuffer+3);
-
- cheader = 0;
- cheader = a;
- cheader <<= 8;
- cheader |= b;
- cheader <<= 8;
- cheader |= c;
- cheader <<= 8;
- cheader |= d;
- if ( head_check( cheader, 0 ) )
- {
- // post( "mp3streamin~ : valid header ( packet=%d)", x->x_inpackets );
- decode_header( &hframe, cheader );
- // print_header_compact( &hframe );
- // when the bitrate change, reinit decoder
- if ( x->x_bitrateindex != hframe.bitrate_index )
- {
- ExitMP3(&mp[x->x_instance]);
- InitMP3(&mp[x->x_instance]);
- x->x_bitrateindex = hframe.bitrate_index;
- }
- }
- else
- {
- post( "mp3streamin~ : error : mp3 packet received without header" );
- // ignore data
- x->x_inwriteposition = 0;
- x->x_inpackets--;
- return( -1 );
- }
-
- // post( "mp3streamin~ : decoding %d bytes framesize=%d", x->x_inwriteposition, hframe.framesize );
- ret =
- decodeMP3(&mp[x->x_instance], (unsigned char*)x->x_inbuffer,
- x->x_inwriteposition, (char *) p, sizeof(out), &pbytes);
-
- switch (ret) {
- case MP3_OK:
- switch (mp[x->x_instance].fr.stereo) {
- case 1:
- case 2:
- alength = ((mp[x->x_instance].fr.stereo==1)?pbytes >> 1 : pbytes >> 2);
- // post( "mp3streamin~ : processed %d samples", alength );
- // update outbuffer contents
- for ( i=0; i<alength; i++ )
- {
- if ( x->x_outunread >= x->x_outbuffersize-2 )
- {
- post( "mp3streamin~ : too much input ... ignored" );
- continue;
- }
- *(x->x_outbuffer+x->x_outwriteposition) = ((t_float)(*p++))/32767.0;
- x->x_outwriteposition = (x->x_outwriteposition + 1)%x->x_outbuffersize;
- *(x->x_outbuffer+x->x_outwriteposition) =
- ((mp[x->x_instance].fr.stereo==2)?((t_float)(*p++))/32767.0 : 0.0);
- x->x_outwriteposition = (x->x_outwriteposition + 1)%x->x_outbuffersize;
- x->x_outunread+=2;
-
- if ( x->x_outunread > MIN_AUDIO_INPUT && !x->x_stream )
- {
- post( "mp3streamin~ : stream connected." );
- x->x_stream = 1;
- }
- }
-
- break;
- default:
- alength = -1;
- break;
- }
- break;
-
- case MP3_NEED_MORE:
- post( "mp3streamin~ : retry lame decoding (more data needed)." );
- alength = 0;
- break;
-
- case MP3_ERR:
- post( "mp3streamin~ : lame decoding failed." );
- alength = -1;
- break;
-
- }
-
- x->x_inwriteposition = 0;
- }
- else
- {
- if ( x->x_outunread == 0 )
- {
- post( "mp3streamin~ : connection closed" );
- mp3streamin_closesocket(x->x_socket);
- x->x_stream = 0;
- x->x_newstream = 0;
- x->x_inpackets = 0;
- x->x_inwriteposition = 0;
- x->x_bitrateindex = -1;
- x->x_socket=-1;
- outlet_symbol( x->x_connectionip, gensym("") );
- }
- }
-
- if ( x->x_graphic && glist_isvisible( x->x_canvas ) )
- {
- /* update graphical read status */
- if ( x->x_inpackets != x->x_dpacket )
- {
- char color[32];
- int minpackets = ( MIN_AUDIO_INPUT/LAME_AUDIO_CHUNK_SIZE )-2; // audio loop has eaten some already
-
-
- sys_vgui(".x%x.c delete rectangle %xSTATUS\n", x->x_canvas, x );
- sys_vgui(".x%x.c delete line %xTHRESHOLD\n", x->x_canvas, x );
- if ( x->x_outunread > 0 )
- {
- t_int width;
-
- if ( x->x_inpackets < (MIN_AUDIO_INPUT/LAME_AUDIO_CHUNK_SIZE)/2 )
- {
- strcpy( color, "red" );
- }
- else
- {
- strcpy( color, "lightgreen" );
- }
- width = rtext_width( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) );
- sys_vgui(".x%x.c create rectangle %d %d %d %d -fill %s -tags %xSTATUS\n",
- x->x_canvas, x->x_obj.te_xpix, x->x_obj.te_ypix-BARHEIGHT-1,
- x->x_obj.te_xpix+(x->x_inpackets*x->x_packetsize*width)/INPUT_BUFFER_SIZE,
- x->x_obj.te_ypix - 1, color, x );
- sys_vgui(".x%x.c create line %d %d %d %d -fill red -tags %xTHRESHOLD\n",
- x->x_canvas, x->x_obj.te_xpix+(minpackets*x->x_packetsize*width)/INPUT_BUFFER_SIZE,
- x->x_obj.te_ypix-BARHEIGHT-1,
- x->x_obj.te_xpix+(minpackets*x->x_packetsize*width)/INPUT_BUFFER_SIZE,
- x->x_obj.te_ypix-1, x );
- x->x_dpacket = x->x_inpackets;
- }
- else
- {
- if ( x->x_shutdown )
- {
- x->x_shutdown=0;
- sys_vgui(".x%x.c delete rectangle %xPBAR\n", x->x_canvas, x );
- sys_vgui(".x%x.c delete line %xTHRESHOLD\n", x->x_canvas, x );
- }
- }
- }
- }
- return alength;
-}
-
-static void mp3streamin_recv(t_mp3streamin *x)
-{
- int ret;
-
- if ( ( ret = recv(x->x_socket, (void*) (x->x_inbuffer + x->x_inwriteposition),
- (size_t)((x->x_inbuffersize-x->x_inwriteposition)),
- MSG_NOSIGNAL) ) < 0 )
- {
- post( "mp3_streamin~ : receive error" );
- perror( "recv" );
- return;
- }
- else
- {
- // post( "streamin~ : received %d bytes at %d on %d ( up to %d)",
- // ret, x->x_inwriteposition, x->x_socket,
- // x->x_inbuffersize-x->x_inwriteposition*sizeof( unsigned long) );
-
- if ( ret == 0 )
- {
- /* initiate the shutdown phase */
- x->x_shutdown=1;
- }
- else
- {
- // check we don't overflow input buffer
- if ( (x->x_inpackets+1)*x->x_packetsize > x->x_inbuffersize )
- {
- post( "mp3streamin~ : too much input...resetting" );
- x->x_inpackets=0;
- x->x_inwriteposition=0;
- return;
- }
- x->x_inpackets++;
- x->x_packetsize=ret;
- if ( x->x_inpackets % 100 == 0 )
- {
- // post( "mp3streamin~ : received %d packets", x->x_inpackets );
- }
- x->x_inwriteposition += ret;
- }
-
- mp3streamin_decode_input(x);
- }
-}
-
-static void mp3streamin_acceptconnection(t_mp3streamin *x)
-{
- struct sockaddr_in incomer_address;
- int sockaddrl = (int) sizeof( struct sockaddr );
-
- int fd = accept(x->x_serversocket, (struct sockaddr*)&incomer_address, &sockaddrl );
-
- if (fd < 0) {
- post("mp3streamin~: accept failed");
- return;
- }
-
- if (x->x_socket > 0) {
- sys_addpollfn(fd, (t_fdpollfn)mp3streamin_recv, x);
- if ( x->x_outunread != 0 )
- {
- post("mp3streamin~: still have some data to decode, retry later you %s.",
- inet_ntoa( incomer_address.sin_addr ));
- mp3streamin_closesocket( fd );
- return;
- }
- post("mp3streamin~: the source has changed to %s.",
- inet_ntoa( incomer_address.sin_addr ));
- mp3streamin_closesocket(x->x_socket);
- }
-
- x->x_socket = fd;
- sys_addpollfn(x->x_socket, (t_fdpollfn)mp3streamin_recv, x);
- outlet_symbol( x->x_connectionip, gensym( inet_ntoa( incomer_address.sin_addr) ) );
-
- if ( x->x_graphic && glist_isvisible( x->x_canvas ) )
- {
- t_int width;
-
- width = rtext_width( glist_findrtext( (t_glist*)x->x_canvas, (t_text *)x ) );
- sys_vgui(".x%x.c create rectangle %d %d %d %d -fill lightblue -tags %xPBAR\n",
- x->x_canvas, x->x_obj.te_xpix, x->x_obj.te_ypix-BARHEIGHT-1,
- x->x_obj.te_xpix + width, x->x_obj.te_ypix - 1, x );
- }
- x->x_stream = 0;
- x->x_newstream = 1;
-
-}
-
-
-static int mp3streamin_startservice(t_mp3streamin* x, int portno)
-{
- struct sockaddr_in server;
- int sockfd;
-
- /* create a socket */
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
-
- if (sockfd < 0)
- {
- sys_sockerror("socket");
- return (0);
- }
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = INADDR_ANY;
-
- /* assign server port number */
- server.sin_port = htons((u_short)portno);
- post("listening to port number %d", portno);
-
- setsocketoptions(sockfd);
-
- /* name the socket */
- if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) {
- sys_sockerror("bind");
- mp3streamin_closesocket(sockfd);
- return (0);
- }
-
- if (listen(sockfd, 5) < 0) {
- sys_sockerror("listen");
- mp3streamin_closesocket(sockfd);
- }
- else
- {
- x->x_serversocket = sockfd;
- sys_addpollfn(x->x_serversocket, (t_fdpollfn)mp3streamin_acceptconnection, x);
- }
-
- return 1;
-}
-
-static void mp3streamin_free(t_mp3streamin *x)
-{
- post( "mp3streamin~ : free %x", x );
- if (x->x_serversocket > 0) {
- post( "mp3streamin~ : closing server socket" );
- mp3streamin_closesocket(x->x_serversocket);
- x->x_serversocket = -1;
- }
- if (x->x_socket > 0) {
- post( "mp3streamin~ : closing socket" );
- mp3streamin_closesocket(x->x_socket);
- x->x_socket = -1;
- }
- if ( x->x_inbuffer ) freebytes( x->x_inbuffer, x->x_inbuffersize );
- if ( x->x_outbuffer ) freebytes( x->x_outbuffer, x->x_outbuffersize*sizeof(t_float) );
- if ( x->x_instance == nbinstances-1 )
- {
- nbinstances--;
- }
-}
-
-static t_int *mp3streamin_perform(t_int *w)
-{
- t_mp3streamin *x = (t_mp3streamin*) (w[1]);
- t_float *out1 = (t_float *)(w[2]);
- t_float *out2 = (t_float *)(w[3]);
- int n = (int)(w[4]);
- int bsize = n;
- int ret;
- int i = 0;
-
- while( n-- )
- {
- if ( ( ( x->x_outunread > MIN_AUDIO_INPUT ) && x->x_newstream ) || // wait the buffer to load
- ( ( x->x_shutdown ) && ( x->x_outunread >= 2 ) ) || // clean disconnection
- ( x->x_stream ) // check that the stream provides enough data
- )
- {
- if ( x->x_newstream && !x->x_shutdown )
- {
- x->x_newstream = 0;
- x->x_stream = 1;
- }
- *out1++=*(x->x_outbuffer+x->x_outreadposition);
- x->x_outreadposition = (x->x_outreadposition + 1)%x->x_outbuffersize;
- *out2++=*(x->x_outbuffer+x->x_outreadposition);
- x->x_outreadposition = (x->x_outreadposition + 1)%x->x_outbuffersize;
- x->x_outunread-=2;
- if ( n == 1 ) x->x_pblocks++;
- }
- else
- {
- *out1++=0.0;
- *out2++=0.0;
- }
- }
-
- if ( ( x->x_outunread <= MIN_AUDIO_INPUT/10 ) && ( x->x_stream ) )
- {
- post( "mp3streamin~ : stream lost (too little input)" );
- x->x_stream = 0;
- x->x_newstream = 1; // waiting for a new stream
- }
-
- if ( x->x_pblocks == LAME_AUDIO_CHUNK_SIZE/bsize )
- {
- x->x_inpackets--;
- x->x_pblocks = 0;
- }
-
-#ifdef DO_MY_OWN_SELECT
- // check new incoming data
- if ( x->x_socket > 0 )
- {
- fd_set readset;
- fd_set exceptset;
-
- FD_ZERO(&readset);
- FD_ZERO(&exceptset);
- FD_SET(x->x_socket, &readset );
- FD_SET(x->x_socket, &exceptset );
-
- if ( select( maxfd+1, &readset, NULL, &exceptset, &ztout ) >0 )
- {
- if ( FD_ISSET( x->x_socket, &readset) || FD_ISSET( x->x_socket, &exceptset ) )
- {
- /* receive data or error and decode it */
- mp3streamin_recv(x);
- }
- }
- }
-#endif
- return (w+5);
-}
-
-static void mp3streamin_dsp(t_mp3streamin *x, t_signal **sp)
-{
- dsp_add(mp3streamin_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
-}
-
-
-static void *mp3streamin_new(t_floatarg fportno, t_floatarg fdographics)
-{
- t_mp3streamin *x;
- int i;
-
- if ( fportno < 0 || fportno > 65535 )
- {
- post( "mp3streamin~ : error : wrong portnumber : %d", (int)fportno );
- return NULL;
- }
- if ( ((int)fdographics != 0) && ((int)fdographics != 1.) )
- {
- post( "mp3streamin~ : error : constructor : mp3streamin~ <portnumber> [graphic flag = 0 | 1 ] ( got = %f)", fdographics );
- return NULL;
- }
-
- x = (t_mp3streamin *)pd_new(mp3streamin_class);
- post( "mp3streamin~ : new %x (instance = %d) %d", x, nbinstances, sizeof( MPSTR ) );
- outlet_new(&x->x_obj, &s_signal);
- outlet_new(&x->x_obj, &s_signal);
- x->x_connectionip = outlet_new(&x->x_obj, &s_symbol);
-
- x->x_serversocket = -1;
- x->x_socket = -1;
- x->x_shutdown = 0;
- x->x_inpackets = 0;
- x->x_dpacket = -1;
-
- x->x_canvas = canvas_getcurrent();
-
- x->x_inbuffersize = INPUT_BUFFER_SIZE;
- x->x_outbuffersize = OUTPUT_BUFFER_SIZE;
- x->x_inbuffer = (char*) getbytes( x->x_inbuffersize );
- memset( x->x_inbuffer, 0x0, INPUT_BUFFER_SIZE );
- x->x_outbuffer = (t_float*) getbytes( x->x_outbuffersize*sizeof(t_float) );
- memset( x->x_outbuffer, 0x0, OUTPUT_BUFFER_SIZE );
-
- if ( !x->x_inbuffer || !x->x_outbuffer )
- {
- post( "mp3streamin~ : could not allocate buffers." );
- return NULL;
- }
-
- if ( nbinstances < MAX_DECODERS )
- {
- x->x_instance = nbinstances++;
- }
- else
- {
- post( "mp3streamin~ : cannot create more decoders (memory issues), sorry" );
- return NULL;
- }
-
- x->x_inwriteposition = 0;
- x->x_outreadposition = 0;
- x->x_outwriteposition = 0;
- x->x_outunread = 0;
-
- ztout.tv_sec = 0;
- ztout.tv_usec = 0;
-
- x->x_graphic = (int)fdographics;
-
- post( "mp3streamin~ : starting service on port %d", (int)fportno );
- mp3streamin_startservice(x, (int)fportno);
-
- // init lame decoder
- mp3streamin_tilde_mpglib_init(x);
-
- return (x);
-}
-
-
-void mp3streamin_tilde_setup(void)
-{
- post( mp3streamin_version );
- mp3streamin_class = class_new(gensym("mp3streamin~"),
- (t_newmethod) mp3streamin_new, (t_method) mp3streamin_free,
- sizeof(t_mp3streamin), CLASS_NOINLET, A_DEFFLOAT, A_DEFFLOAT, A_NULL);
-
- class_addmethod(mp3streamin_class, nullfn, gensym("signal"), 0);
- class_addmethod(mp3streamin_class, (t_method) mp3streamin_dsp, gensym("dsp"), 0);
-}
diff --git a/mp3live~/mp3streamout~.c b/mp3live~/mp3streamout~.c
deleted file mode 100644
index 33555ce..0000000
--- a/mp3live~/mp3streamout~.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/* ------------------------ mp3streamout~ ------------------------------------- */
-/* */
-/* Tilde object to send mp3-stream to a peer using mp3streamin~. */
-/* Written by Yves Degoyon (ydegoyon@free.fr). */
-/* Tarballs and updates @ http://ydegoyon.free.fr */
-/* */
-/* This program is free software; you can redistribute it and/or */
-/* modify it under the terms of the GNU General Public License */
-/* as published by the Free Software Foundation; either version 2 */
-/* of the License, or (at your option) any later version. */
-/* */
-/* See file LICENSE for further informations on licensing terms. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
-/* GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* */
-/* Based on PureData by Miller Puckette and others. */
-/* Uses the LAME MPEG 1 Layer 3 encoding library (lame_enc.dll) which can */
-/* be found at http://www.cdex.n3.net. */
-/* */
-/* "I'd sell my soul to god" */
-/* "If it could take away the pain." */
-/* Theo Hakola -- */
-/* ---------------------------------------------------------------------------- */
-
-#include <sys/types.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#ifndef __APPLE__
-#include <malloc.h>
-#endif
-#include <ctype.h>
-#ifdef _WIN32
-#include <io.h>
-#include <windows.h>
-#include <winsock.h>
-#include <windef.h>
-#else
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <time.h>
-#include <sys/time.h>
-#define SOCKET_ERROR -1
-#endif
-
-#if defined(__APPLE__) || defined(_WIN32)
-#define MSG_NOSIGNAL 0
-#endif
-
-#include <lame/lame.h> /* lame encoder stuff */
-
-#include "m_pd.h" /* standard pd stuff */
-
-#include "mpg123.h" /* sub-library MPGLIB included in lame */
-/* useful debugging functions from mpglib */
-extern int decode_header( struct frame* fr, unsigned long newhead );
-extern void print_header_compact( struct frame* fr );
-extern int head_check( unsigned long head, int check_layer );
-
-#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
-
-#define MAXDATARATE 320 /* maximum mp3 data rate is 320kbit/s */
-#define STRBUF_SIZE 32
-
-static char *mp3streamout_version = "mp3streamout~: mp3 peer-to-peer streamer version 0.3, written by ydegoyon@free.fr";
-
-static t_class *mp3streamout_class;
-
-typedef struct _mp3streamout
-{
- t_object x_obj;
-
- /* LAME stuff */
- int x_lame; /* info about encoder status */
- int x_lamechunk; /* chunk size for LAME encoder */
- int x_mp3size; /* number of returned mp3 samples */
-
- /* 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 */
- char *x_mp3outbuf; /* data returned by LAME -> our mp3 stream */
- short *x_buffer; /* data to be buffered */
- int x_bytesbuffered; /* number of unprocessed bytes in buffer */
- int x_start;
-
- /* 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 */
-
- /* connection data */
- int x_fd; /* info about connection status */
- int x_outpackets; /* mp3 packets sent */
-
- t_float x_f; /* float needed for signal input */
-
- lame_global_flags* lgfp;
-} t_mp3streamout;
-
-
- /* encode PCM data to mp3 stream */
-static void mp3streamout_encode(t_mp3streamout *x)
-{
- unsigned short i, wp;
- int err = -1;
- int n = x->x_lamechunk;
-
-#ifdef UNIX
- if(x->x_lamechunk < (int)sizeof(x->x_mp3inbuf))
-#else
- if(x->x_lamechunk < sizeof(x->x_mp3inbuf))
-#endif
- {
- error("not enough memory!");
- return;
- }
-
- /* on start/reconnect set outpoint that it not interferes with inpoint */
- if(x->x_start == -1)
- {
- post("mp3streamout~: initializing buffers");
- /* 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);
- }
- else if(x->x_inp < (2 * x->x_lamechunk))
- {
- x->x_outp = (short) MY_MP3_MALLOC_IN_SIZE - (2.5 * x->x_lamechunk);
- }
- x->x_start = 1;
- }
- if((unsigned short)(x->x_outp - x->x_inp) < x->x_lamechunk)error("mp3streamout~: buffers overlap!");
-
- i = MY_MP3_MALLOC_IN_SIZE - x->x_outp;
-
- /* read from buffer */
- if(x->x_lamechunk <= i)
- {
- /* 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];
- }
- x->x_outp += x->x_lamechunk;
- }
- else /* split data */
- {
- for(wp = 0; wp < i; wp++) /* data at end of buffer */
- {
- x->x_mp3inbuf[wp] = x->x_buffer[wp + x->x_outp];
- }
-
- for(wp = i; wp < x->x_lamechunk; wp++) /* write rest of data at beginning of buffer */
- {
- x->x_mp3inbuf[wp] = x->x_buffer[wp - i];
- }
- x->x_outp = x->x_lamechunk - i;
- }
-
- /* 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_mp3outbuf, MY_MP3_MALLOC_OUT_SIZE);
- x->x_mp3size+=lame_encode_flush( x->lgfp, x->x_mp3outbuf+x->x_mp3size, MY_MP3_MALLOC_OUT_SIZE-x->x_mp3size );
- // post( "mp3streamout~ : encoding returned %d frames", x->x_mp3size );
-
- /* check result */
- if(x->x_mp3size<0)
- {
- lame_close( x->lgfp );
- error("mp3streamout~: lame_encode_buffer_interleaved failed (%d)", x->x_mp3size);
- x->x_lame = -1;
- }
-}
-
- /* stream mp3 to the peer */
-static void mp3streamout_stream(t_mp3streamout *x)
-{
- int count = -1, i;
- struct frame hframe;
-
- /* header needs to be included in each packet */
-
- for( i=0; i<x->x_mp3size; i++ )
- {
- // track valid data
- if ( head_check( *((unsigned long*)x->x_mp3outbuf+i), 3 ) )
- {
- // post( "valid header emitted @ %d (byte %d)", i, i*sizeof(unsigned long) );
- }
- }
-
- count = send(x->x_fd, x->x_mp3outbuf, x->x_mp3size, MSG_NOSIGNAL);
- if(count < 0)
- {
- error("mp3streamout~: could not send encoded data to the peer (%d)", count);
- lame_close( x->lgfp );
- x->x_lame = -1;
-#ifndef UNIX
- closesocket(x->x_fd);
-#else
- close(x->x_fd);
-#endif
- x->x_fd = -1;
- outlet_float(x->x_obj.ob_outlet, 0);
- }
- else
- {
- x->x_outpackets++;
- if ( x->x_outpackets%100 == 0 )
- {
- // post( "mp3streamout~ : emitted %d bytes (packets = %d)", count, x->x_outpackets );
- }
- }
- if((count > 0)&&(count != x->x_mp3size))
- {
- error("mp3streamout~: %d bytes skipped", x->x_mp3size - count);
- }
-}
-
-
- /* buffer data as channel interleaved PCM */
-static t_int *mp3streamout_perform(t_int *w)
-{
- t_float *in1 = (t_float *)(w[1]); /* left audio inlet */
- t_float *in2 = (t_float *)(w[2]); /* right audio inlet */
- t_mp3streamout *x = (t_mp3streamout *)(w[3]);
- int n = (int)(w[4]); /* number of samples */
- unsigned short i,wp;
- float in;
-
- /* 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 )
- {
- /* the place between inp and MY_MP3_MALLOC_IN_SIZE */
- /* is big enough to hold the data */
-
- 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) { in = -1.0; }
- 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 */
-
- 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
- {
- 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);
- }
- x->x_inp = n - i; /* new writeposition in buffer */
- }
-
- if((x->x_fd >= 0)&&(x->x_lame >= 0))
- {
- /* count buffered samples when things are running */
- x->x_bytesbuffered += n;
-
- /* encode and send to the peer */
- if(x->x_bytesbuffered > x->x_lamechunk)
- {
- mp3streamout_encode(x); /* encode to mp3 */
- mp3streamout_stream(x); /* stream mp3 to the peer */
- x->x_bytesbuffered -= x->x_lamechunk;
- }
- }
- else
- {
- x->x_start = -1;
- }
- return (w+5);
-}
-
-static void mp3streamout_dsp(t_mp3streamout *x, t_signal **sp)
-{
- dsp_add(mp3streamout_perform, 4, sp[0]->s_vec, sp[1]->s_vec, x, sp[0]->s_n);
-}
-
- /* initialize the lame library */
-static void mp3streamout_tilde_lame_init(t_mp3streamout *x)
-{
- int ret;
- x->lgfp = lame_init(); /* set default parameters for now */
-
-#ifndef UNIX
- /* load lame_enc.dll library */
- HINSTANCE dll;
- dll=LoadLibrary("lame_enc.dll");
- if(dll==NULL)
- {
- error("mp3streamout~: error loading lame_enc.dll");
- closesocket(x->x_fd);
- x->x_fd = -1;
- outlet_float(x->x_obj.ob_outlet, 0);
- post("mp3streamout~: connection closed");
- return;
- }
-#endif
- {
- const char *lameVersion = get_lame_version();
- post( "mp3streamout~ : using lame version : %s", lameVersion );
- }
-
- /* 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 );
- lame_set_brate( x->lgfp, x->x_bitrate );
- lame_set_mode( x->lgfp, x->x_mp3mode );
- lame_set_quality( x->lgfp, x->x_mp3quality );
- lame_set_emphasis( x->lgfp, 1 );
- lame_set_original( x->lgfp, 1 );
- lame_set_copyright( x->lgfp, 1 ); /* viva free music societies !!! */
- 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( "mp3streamout~ : error : lame params initialization returned : %d", ret );
- } else {
- x->x_lame=1;
- /* magic formula copied from windows dll for MPEG-I */
- x->x_lamechunk = 2*1152;
-
- post( "mp3streamout~ : lame initialization done. (%d)", x->x_lame );
- }
- lame_init_bitstream( x->lgfp );
-}
-
- /* connect to the peer */
-static void mp3streamout_connect(t_mp3streamout *x, t_symbol *hostname, t_floatarg fportno)
-{
- struct sockaddr_in csocket;
- struct hostent *hp;
- int portno = fportno; /* get port from message box */
-
- /* variables used for communication with the peer */
- const char *buf = 0;
- char resp[STRBUF_SIZE];
- unsigned int len;
- int sockfd;
-
-#ifndef UNIX
- unsigned int ret;
-#else
- int ret;
-#endif
-
- if (x->x_fd >= 0)
- {
- error("mp3streamout~: already connected");
- return;
- }
-
- sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sockfd < 0)
- {
- error("mp3streamout~: internal error while attempting to open socket");
- return;
- }
-
- /* connect socket using hostname provided in command line */
- csocket.sin_family = AF_INET;
- hp = gethostbyname(hostname->s_name);
- if (hp == 0)
- {
- post("mp3streamout~: bad host?");
-#ifndef UNIX
- closesocket(sockfd);
-#else
- close(sockfd);
-#endif
- return;
- }
- memcpy((char *)&csocket.sin_addr, (char *)hp->h_addr, hp->h_length);
-
- /* assign client port number */
- csocket.sin_port = htons((unsigned short)portno);
-
- /* try to connect. */
- post("mp3streamout~: connecting to port %d", portno);
- if (connect(sockfd, (struct sockaddr *) &csocket, sizeof (csocket)) < 0)
- {
- error("mp3streamout~: connection failed!\n");
-#ifndef UNIX
- closesocket(sockfd);
-#else
- close(sockfd);
-#endif
- return;
- }
-
- x->x_fd = sockfd;
- x->x_outpackets = 0;
- outlet_float( x->x_obj.ob_outlet, 1 );
- post( "mp3streamout~ : connected to peer" );
-
- mp3streamout_tilde_lame_init(x);
-
-}
-
- /* close connection to the peer */
-static void mp3streamout_disconnect(t_mp3streamout *x)
-{
-
- int err = -1;
- if(x->x_lame >= 0)
- {
- /* ignore remaining bytes */
- if ( x->x_mp3size = lame_encode_flush( x->lgfp, x->x_mp3outbuf, 0) < 0 ) {
- post( "mp3streamout~ : warning : remaining encoded bytes" );
- }
- lame_close( x->lgfp );
- x->x_lame = -1;
- post("mp3streamout~: encoder stream closed");
- }
-
- if(x->x_fd >= 0) /* close socket */
- {
-#ifndef UNIX
- closesocket(x->x_fd);
-#else
- close(x->x_fd);
-#endif
- x->x_fd = -1;
- outlet_float( x->x_obj.ob_outlet, 0 );
- post("mp3streamout~: connection closed");
- }
-}
-
- /* settings for mp3 encoding */
-static void mp3streamout_mpeg(t_mp3streamout *x, t_floatarg fbitrate,
- t_floatarg fmode, t_floatarg fquality)
-{
- if ( fbitrate != 32 && fbitrate != 40 && fbitrate != 48 && fbitrate != 56 &&
- fbitrate != 64 && fbitrate != 80 && fbitrate != 96 && fbitrate != 112 &&
- fbitrate != 128 && fbitrate != 160 && fbitrate != 192 && fbitrate != 224 &&
- fbitrate != 256 && fbitrate != 320 ) {
- post( "mp3streamout~ : wrong bitrate." );
- return;
- }
- if ( fmode <0 || fmode>2 ) {
- post( "mp3streamout~ : wrong mp3 mode." );
- if ( fmode == 3 )
- {
- post( "mp3streamout~ : mone is not supported by streamout~ for now." );
- }
- return;
- }
- /* there is a bug in lame 3.92 and quality below 5 will not work */
- /* WAIT FOR A FIX */
- if ( fquality <5 || fquality>9 ) {
- post( "mp3streamout~ : wrong quality." );
- return;
- }
- x->x_bitrate = fbitrate;
- x->x_mp3mode = fmode;
- x->x_mp3quality = (int)fquality;
- post("mp3streamout~: setting mp3 stream to %dHz, %dkbit/s, mode %d, quality %d",
- x->x_samplerate, x->x_bitrate, x->x_mp3mode, x->x_mp3quality);
- mp3streamout_tilde_lame_init(x);
-}
-
- /* print settings */
-static void mp3streamout_print(t_mp3streamout *x)
-{
- const char * buf = 0;
-
- post(mp3streamout_version);
- post(" LAME mp3 settings:\n"
- " output sample rate: %d Hz\n"
- " 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;
- }
- post(" mode: %s\n"
- " quality: %d", buf, x->x_mp3quality);
-#ifndef UNIX
- if(x->x_lamechunk!=0)post(" calculated mp3 chunk size: %d", x->x_lamechunk);
-#else
- post(" mp3 chunk size: %d", x->x_lamechunk);
-#endif
- if(x->x_samplerate!=sys_getsr())
- {
- post(" resampling from %d to %d Hz!", (int)sys_getsr(), x->x_samplerate);
- }
-}
-
- /* clean up */
-static void mp3streamout_free(t_mp3streamout *x)
-{
-
- if(x->x_lame >= 0)
- lame_close( x->lgfp );
-
- if(x->x_fd >= 0)
-#ifndef UNIX
- closesocket(x->x_fd);
-#else
- close(x->x_fd);
-#endif
- freebytes(x->x_mp3inbuf, MY_MP3_MALLOC_IN_SIZE*sizeof(short));
- freebytes(x->x_mp3outbuf, MY_MP3_MALLOC_OUT_SIZE);
- freebytes(x->x_buffer, MY_MP3_MALLOC_IN_SIZE*sizeof(short));
-}
-
-static void *mp3streamout_new(void)
-{
- t_mp3streamout *x = (t_mp3streamout *)pd_new(mp3streamout_class);
- inlet_new (&x->x_obj, &x->x_obj.ob_pd, gensym ("signal"), gensym ("signal"));
- outlet_new( &x->x_obj, &s_float );
- x->lgfp = NULL;
- x->x_fd = -1;
- x->x_outpackets = 0;
- x->x_lame = -1;
- x->x_samplerate = sys_getsr();
- x->x_bitrate = 128;
- x->x_mp3mode = 1;
- x->x_mp3quality = 5;
- x->x_mp3inbuf = getbytes(MY_MP3_MALLOC_IN_SIZE*sizeof(short)); /* buffer for encoder input */
- x->x_mp3outbuf = getbytes(MY_MP3_MALLOC_OUT_SIZE); /* our mp3 stream */
- x->x_buffer = getbytes(MY_MP3_MALLOC_IN_SIZE*sizeof(short)); /* what we get from pd, converted to PCM */
- if ((!x->x_buffer)||(!x->x_mp3inbuf)||(!x->x_mp3outbuf)) /* check buffers... */
- {
- error("out of memory!");
- }
- x->x_bytesbuffered = 0;
- x->x_inp = 0;
- x->x_outp = 0;
- x->x_start = -1;
- return(x);
-}
-
-void mp3streamout_tilde_setup(void)
-{
- post(mp3streamout_version);
- mp3streamout_class = class_new(gensym("mp3streamout~"), (t_newmethod)mp3streamout_new, (t_method)mp3streamout_free,
- sizeof(t_mp3streamout), 0, 0);
- CLASS_MAINSIGNALIN(mp3streamout_class, t_mp3streamout, x_f );
- class_addmethod(mp3streamout_class, (t_method)mp3streamout_dsp, gensym("dsp"), 0);
- class_addmethod(mp3streamout_class, (t_method)mp3streamout_connect, gensym("connect"), A_SYMBOL, A_FLOAT, 0);
- class_addmethod(mp3streamout_class, (t_method)mp3streamout_disconnect, gensym("disconnect"), 0);
- class_addmethod(mp3streamout_class, (t_method)mp3streamout_mpeg, gensym("mpeg"), A_FLOAT, A_FLOAT, A_FLOAT, 0);
- class_addmethod(mp3streamout_class, (t_method)mp3streamout_print, gensym("print"), 0);
-}
-
diff --git a/mp3live~/mpglib.h b/mp3live~/mpglib.h
deleted file mode 100644
index 1f4ef9a..0000000
--- a/mp3live~/mpglib.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// #include "lame-analysis.h"
-
-#define NOANALYSIS
-
-#ifndef NOANALYSIS
-extern plotting_data *mpg123_pinfo;
-#endif
-
-struct buf {
- unsigned char *pnt;
- long size;
- long pos;
- struct buf *next;
- struct buf *prev;
-};
-
-struct framebuf {
- struct buf *buf;
- long pos;
- struct frame *next;
- struct frame *prev;
-};
-
-typedef struct mpstr_tag {
- struct buf *head,*tail;
- int vbr_header; /* 1 if valid Xing vbr header detected */
- int num_frames; /* set if vbr header present */
- int enc_delay; /* set if vbr header present */
- int enc_padding; /* set if vbr header present */
- int header_parsed;
- int side_parsed;
- int data_parsed;
- int free_format; /* 1 = free format frame */
- int old_free_format; /* 1 = last frame was free format */
- int bsize;
- int framesize;
- int ssize;
- int dsize;
- int fsizeold;
- int fsizeold_nopadding;
- struct frame fr;
- unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
- real hybrid_block[2][2][SBLIMIT*SSLIMIT];
- int hybrid_blc[2];
- unsigned long header;
- int bsnum;
- real synth_buffs[2][2][0x110];
- int synth_bo;
- int sync_bitstream;
-
-} MPSTR, *PMPSTR;
-
-
-#if ( defined(_MSC_VER) || defined(__BORLANDC__) )
- typedef int BOOL; /* windef.h contains the same definition */
-#else
- #define BOOL int
-#endif
-
-#define MP3_ERR -1
-#define MP3_OK 0
-#define MP3_NEED_MORE 1
-
-
-
diff --git a/mp3live~/test-streaming-mp3.pd b/mp3live~/test-streaming-mp3.pd
deleted file mode 100644
index e9e6b2e..0000000
--- a/mp3live~/test-streaming-mp3.pd
+++ /dev/null
@@ -1,96 +0,0 @@
-#N canvas 15 9 986 678 10;
-#X msg 63 58 bang;
-#X obj 63 78 openpanel;
-#X obj 63 100 t s b;
-#X obj 63 137 pack s s;
-#X obj 99 100 float \$0;
-#X text 51 39 Step 1 : Load a sound file;
-#X obj 117 137 makefilename %d-sample;
-#X msg 443 280 \; pd dsp 1;
-#X msg 509 280 \; pd dsp 0;
-#X obj 454 254 loadbang;
-#X obj 62 217 mp3streamout~;
-#X floatatom 63 240 5 0 0;
-#X obj 62 181 readsf~;
-#X msg 62 158 open \$1 \$2;
-#X msg 33 148 1;
-#X msg 265 185 disconnect;
-#X obj 63 117 route float;
-#X msg 569 47 bang;
-#X obj 569 67 openpanel;
-#X obj 569 89 t s b;
-#X obj 569 126 pack s s;
-#X obj 605 89 float \$0;
-#X text 557 28 Step 1 : Load a sound file;
-#X obj 623 126 makefilename %d-sample;
-#X obj 568 206 mp3streamout~;
-#X floatatom 569 229 5 0 0;
-#X obj 568 170 readsf~;
-#X msg 568 147 open \$1 \$2;
-#X msg 539 137 1;
-#X msg 784 177 disconnect;
-#X obj 569 106 route float;
-#X obj 364 462 dac~;
-#X obj 361 438 *~;
-#X floatatom 416 465 5 0 0;
-#X symbolatom 459 437 15 0 0;
-#X obj 407 440 / 100;
-#X obj 122 470 dac~;
-#X obj 119 446 *~;
-#X floatatom 174 473 5 0 0;
-#X symbolatom 217 445 10 0 0;
-#X obj 165 448 / 100;
-#X obj 96 419 mp3streamin~ 5001 1;
-#X obj 345 410 mp3streamin~ 5000 1;
-#X msg 777 149 connect yves 5001;
-#X msg 246 228 mpeg 32 2 5;
-#X msg 246 228 mpeg 32 2 5;
-#X msg 246 264 mpeg 224 2 5;
-#X msg 258 157 connect localhost 5000;
-#X msg 263 125 connect dregs 5000;
-#X connect 0 0 1 0;
-#X connect 1 0 2 0;
-#X connect 2 0 3 0;
-#X connect 2 1 4 0;
-#X connect 3 0 13 0;
-#X connect 4 0 16 0;
-#X connect 6 0 3 1;
-#X connect 9 0 7 0;
-#X connect 10 0 11 0;
-#X connect 12 0 10 0;
-#X connect 12 0 10 1;
-#X connect 13 0 12 0;
-#X connect 14 0 12 0;
-#X connect 15 0 10 0;
-#X connect 16 0 6 0;
-#X connect 17 0 18 0;
-#X connect 18 0 19 0;
-#X connect 19 0 20 0;
-#X connect 19 1 21 0;
-#X connect 20 0 27 0;
-#X connect 21 0 30 0;
-#X connect 23 0 20 1;
-#X connect 24 0 25 0;
-#X connect 26 0 24 0;
-#X connect 26 0 24 1;
-#X connect 27 0 26 0;
-#X connect 28 0 26 0;
-#X connect 29 0 24 0;
-#X connect 30 0 23 0;
-#X connect 32 0 31 0;
-#X connect 32 0 31 1;
-#X connect 33 0 35 0;
-#X connect 35 0 32 1;
-#X connect 37 0 36 0;
-#X connect 37 0 36 1;
-#X connect 38 0 40 0;
-#X connect 40 0 37 1;
-#X connect 41 0 37 0;
-#X connect 41 2 39 0;
-#X connect 42 0 32 0;
-#X connect 42 2 34 0;
-#X connect 43 0 24 0;
-#X connect 44 0 10 0;
-#X connect 46 0 10 0;
-#X connect 47 0 10 0;
-#X connect 48 0 10 0;