diff --git a/Engine/Makefile b/Engine/Makefile index bdac3e5..638dd5e 100644 --- a/Engine/Makefile +++ b/Engine/Makefile @@ -1,6 +1,7 @@ SRCS= \ Server.C \ + Peak_Server.C \ Timeline_Server.C \ main.C \ Audio_File.C \ diff --git a/Engine/Peak_Server.C b/Engine/Peak_Server.C index 436a719..93bd619 100644 --- a/Engine/Peak_Server.C +++ b/Engine/Peak_Server.C @@ -17,6 +17,12 @@ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*******************************************************************************/ +#include "Peak_Server.H" + +#include +#include +#include + /* Peak Server The peak server streams peak data to any timeline editors or other clients that ask for it. @@ -27,6 +33,59 @@ Response looks like (in binary floats): - > length min max min max min max + > channels length min max min max min max + length ... */ + +#include "Audio_File.H" +#include "Peaks.H" + +typedef unsigned long tick_t; + + +#define PEAK_PORT 6100 + +void +Peak_Server::handle_new ( int s ) +{ + printf( "new connection\n" ); +} + +void +Peak_Server::handle_hang_up ( int s ) +{ + printf( "hangup\n" ); +} + +void +Peak_Server::handle_request ( int s, const char *buf, int l ) +{ + printf( "request: %s", buf ); + + char source[512]; + float fpp; + tick_t start, end; + + if ( 4 != sscanf( buf, "read_peaks \"%[^\"]\" %f %lu %lu", source, &fpp, &start, &end ) ) + fprintf( stderr, "error: malformed peak request!\n" ); + + Audio_File *af = Audio_File::from_file( source ); + + int channels = af->channels(); + + send( s, &channels, sizeof( int ), 0 ); + + for ( int i = 0; i < af->channels(); ++i ) + { + const Peaks *pk = af->peaks( i ); + + int peaks = pk->fill_buffer( fpp, start, end ); + + send( s, &peaks, sizeof( int ), 0 ); + + send( s, pk->peakbuf(), peaks * sizeof( Peak ), 0 ); + } + + delete af; +} diff --git a/Engine/Peak_Server.H b/Engine/Peak_Server.H new file mode 100644 index 0000000..f06465d --- /dev/null +++ b/Engine/Peak_Server.H @@ -0,0 +1,40 @@ + +/*******************************************************************************/ +/* Copyright (C) 2008 Jonathan Moore Liles */ +/* */ +/* 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; see the file COPYING. If not,write to the Free Software */ +/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/*******************************************************************************/ + +#pragma once + +#include "Server.H" + +class Peak_Server : public Server +{ + +protected: + + void handle_new ( int s ); + void handle_hang_up ( int s ); + void handle_request ( int s, const char *s, int l ); + +public: + + Peak_Server ( int port ) : Server ( port ) + { + fork( true ); + echo( false ); + } +}; diff --git a/Engine/Peaks.C b/Engine/Peaks.C index c8b56b5..1591d7b 100644 --- a/Engine/Peaks.C +++ b/Engine/Peaks.C @@ -38,27 +38,33 @@ #include -Peaks::peakbuffer Peaks::peakbuf; +Peaks::peakbuffer Peaks::_peakbuf; /** Prepare a buffer of peaks from /s/ to /e/ for reading. Must be * called before any calls to operator[] */ -void +int Peaks::fill_buffer ( float fpp, int s, int e ) const { _fpp = fpp; - if ( fpp < _peaks->chunksize ) + /* FIXME: repair this */ +// if ( fpp < _peaks->chunksize ) { /* looks like we're going to have to switch to a higher resolution peak file or read directly from the source */ read_peaks( s, e, (e - s) / fpp, fpp ); + + /* FIXME: are we *SURE* we got them all? */ + return e - s; } - else - { - /* we'll just downsample on the fly in this case--no need for extra copying into - the buffer */ - } + +/* else */ +/* { */ +/* /\* we'll just downsample on the fly in this case--no need for extra copying into */ +/* the buffer *\/ */ +/* } */ + } @@ -123,19 +129,19 @@ Peaks::read_peaks ( int s, int e, int npeaks, int chunksize ) const { printf( "reading peaks %d @ %d\n", npeaks, chunksize ); - if ( peakbuf.size < npeaks ) + if ( _peakbuf.size < npeaks ) { - peakbuf.size = npeaks; -// printf( "reallocating peak buffer %li\n", peakbuf.size ); - peakbuf.buf = (peakdata*)realloc( peakbuf.buf, sizeof( peakdata ) + (peakbuf.size * sizeof( Peak )) ); + _peakbuf.size = npeaks; +// printf( "reallocating peak buffer %li\n", _peakbuf.size ); + _peakbuf.buf = (peakdata*)realloc( _peakbuf.buf, sizeof( peakdata ) + (_peakbuf.size * sizeof( Peak )) ); } _clip->open(); _clip->seek( s ); - peakbuf.offset = s; - peakbuf.buf->chunksize = chunksize; - peakbuf.len = clip_read_peaks( peakbuf.buf->data, npeaks, chunksize ); + _peakbuf.offset = s; + _peakbuf.buf->chunksize = chunksize; + _peakbuf.len = clip_read_peaks( _peakbuf.buf->data, npeaks, chunksize ); _clip->close(); } @@ -149,17 +155,17 @@ Peaks::peak ( nframes_t start, nframes_t end ) const if ( _fpp < _peaks->chunksize ) { - assert( _fpp == peakbuf.buf->chunksize ); + assert( _fpp == _peakbuf.buf->chunksize ); - start = (start - peakbuf.offset) / peakbuf.buf->chunksize; - end = (end - peakbuf.offset) / peakbuf.buf->chunksize; + start = (start - _peakbuf.offset) / _peakbuf.buf->chunksize; + end = (end - _peakbuf.offset) / _peakbuf.buf->chunksize; - if ( end > peakbuf.len ) - end = peakbuf.len; + if ( end > _peakbuf.len ) + end = _peakbuf.len; -// assert( peakbuf.len > start ); +// assert( _peakbuf.len > start ); - downsample( peakbuf.buf->data, start, end, &p.max, &p.min ); + downsample( _peakbuf.buf->data, start, end, &p.max, &p.min ); } else { @@ -175,17 +181,18 @@ Peaks::peak ( nframes_t start, nframes_t end ) const /* virtual array. Index is a Pixel value, and it returns the * (resampled) peaks for that pixel based on the current timeline * zoom. */ -Peak & -Peaks::operator[] ( int X ) const -{ - Peak p; - p.min = 0; - p.max = 0; - return p; -// return peak( timeline->x_to_ts( X ), timeline->x_to_ts( X + 1 ) ); +/* Peak & */ +/* Peaks::operator[] ( int X ) const */ +/* { */ -} +/* Peak p; */ +/* p.min = 0; */ +/* p.max = 0; */ +/* return p; */ +/* // return peak( timeline->x_to_ts( X ), timeline->x_to_ts( X + 1 ) ); */ + +/* } */ const char * diff --git a/Engine/Peaks.H b/Engine/Peaks.H index e5b1455..0f876f9 100644 --- a/Engine/Peaks.H +++ b/Engine/Peaks.H @@ -54,7 +54,7 @@ class Peaks } }; - static peakbuffer peakbuf; + static peakbuffer _peakbuf; Audio_File *_clip; int _channel; @@ -96,10 +96,11 @@ public: _channel = 0; } + Peak *peakbuf ( void ) const { return Peaks::_peakbuf.buf->data; } void clip ( Audio_File *c ) { _clip = c; } void channel ( int v ) { _channel = v; } - void fill_buffer ( float fpp, int s, int e ) const; + int fill_buffer ( float fpp, int s, int e ) const; void downsample ( Peak *peaks, int s, int e, float *mhi, float *mlo ) const; void read ( int X, float *hi, float *lo ) const; diff --git a/Engine/Server.C b/Engine/Server.C index a92a038..c8ab041 100644 --- a/Engine/Server.C +++ b/Engine/Server.C @@ -83,6 +83,8 @@ Server::listen_on_port ( int port ) Server::Server ( int port ) { _port = port; + _echo = false; + _fork = false; } void @@ -159,7 +161,7 @@ Server::run ( void ) else { - if ( echos() ) + if ( echo() ) /* echo to others */ for ( int j = maxfd; j-- ; ) { diff --git a/Engine/Server.H b/Engine/Server.H index 28bdb30..5eaa6b5 100644 --- a/Engine/Server.H +++ b/Engine/Server.H @@ -17,10 +17,14 @@ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*******************************************************************************/ +#pragma once + class Server { int _port; + bool _echo; + bool _fork; static int listen_on_port ( int port ); @@ -29,9 +33,13 @@ public: Server ( int port ); void run ( void ); + bool echo ( void ) { return _echo; } + bool fork ( void ) { return _fork; } + void echo ( bool b ) { _echo = b; } + void fork ( bool b) { _fork = b; } + protected: - virtual bool echos ( void ) { return true; } virtual void handle_hang_up ( int s ) = 0; virtual void handle_new ( int s ) = 0; diff --git a/Engine/Timeline_Server.H b/Engine/Timeline_Server.H index 86e5b45..262068a 100644 --- a/Engine/Timeline_Server.H +++ b/Engine/Timeline_Server.H @@ -34,5 +34,7 @@ public: Timeline_Server ( int port ) : Server ( port ) { + fork( false ); + echo( true ); } }; diff --git a/Engine/main.C b/Engine/main.C index 854654b..1ba4598 100644 --- a/Engine/main.C +++ b/Engine/main.C @@ -26,6 +26,7 @@ #include "Timeline_Server.H" +#include "Peak_Server.H" /* TODO: @@ -60,7 +61,13 @@ int main ( int argc, char **argv ) { - Timeline_Server tls( 6110 ); - tls.run(); +/* Timeline_Server tls( 6110 ); */ + +/* tls.run(); */ + + + Peak_Server pks( 6111 ); + + pks.run(); }