@@ -0,0 +1,30 @@ | |||
SRCS= \ | |||
Server.C \ | |||
Timeline_Server.C \ | |||
main.C \ | |||
Audio_File.C \ | |||
Audio_File_SF.C \ | |||
Peaks.C \ | |||
Loggable.C \ | |||
OBJS=$(SRCS:.C=.o) | |||
.PHONEY: all clean install dist valgrind | |||
all: engine | |||
$(OBJS): Makefile | |||
include ../make.inc | |||
engine: $(OBJS) | |||
$(CXX) $(CXXFLAGS) $(INCLUDES) $(LIBS) $(OBJS) -o $@ | |||
clean: | |||
rm -f $(OBJS) engine makedepend | |||
valgrind: | |||
valgrind ./test | |||
include makedepend |
@@ -0,0 +1,32 @@ | |||
/*******************************************************************************/ | |||
/* 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. */ | |||
/*******************************************************************************/ | |||
/* Peak Server | |||
The peak server streams peak data to any timeline editors or other clients that ask for it. | |||
Peak request looks like: | |||
> read_peaks "foo.wav" fpp start end | |||
Response looks like (in binary floats): | |||
> length min max min max min max | |||
*/ |
@@ -0,0 +1,177 @@ | |||
/*******************************************************************************/ | |||
/* 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. */ | |||
/*******************************************************************************/ | |||
#include "Server.H" | |||
#include <netdb.h> | |||
#include <netinet/in.h> | |||
#include <unistd.h> | |||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <errno.h> | |||
#include <sys/socket.h> | |||
#include <sys/types.h> | |||
#include <sys/select.h> | |||
/* Generic TCP server class */ | |||
#define MAX_HOST_NAME 512 | |||
/** open a socket listening on TCP port /port/. Returns -1 in case of error. */ | |||
int | |||
Server::listen_on_port ( int port ) | |||
{ | |||
int s; | |||
char name[ MAX_HOST_NAME + 1 ]; | |||
struct sockaddr_in sa; | |||
struct hostent *hp; | |||
memset( &sa, 0, sizeof( sa ) ); | |||
gethostname( name, MAX_HOST_NAME ); | |||
hp = gethostbyname( name ); | |||
sa.sin_family = hp->h_addrtype; | |||
sa.sin_port = htons( port ); | |||
sa.sin_addr.s_addr = INADDR_ANY; | |||
if ( ( s = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) | |||
{ | |||
printf( "Could not create command socket!" ); | |||
return -1; | |||
} | |||
int yes = 1; | |||
if ( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char * )&yes, sizeof( int ) ) < 0 ) | |||
{ | |||
close( s ); | |||
return -1; | |||
} | |||
if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 ) | |||
{ | |||
printf( "bind: %s", strerror( errno ) ); | |||
close( s ); | |||
return -1; | |||
} | |||
listen( s, 1 ); | |||
return s; | |||
} | |||
Server::Server ( int port ) | |||
{ | |||
_port = port; | |||
} | |||
void | |||
Server::run ( void ) | |||
{ | |||
int server; /* server socket */ | |||
if ( ( server = listen_on_port( _port ) ) < 0 ) | |||
/* error */; | |||
fd_set master; | |||
fd_set read_fds; | |||
int maxfd; | |||
FD_ZERO( &master ); | |||
FD_ZERO( &read_fds ); | |||
FD_SET( server, &master ); | |||
maxfd = server; | |||
for ( ;; ) | |||
{ | |||
read_fds = master; | |||
if ( select( maxfd + 1, &read_fds, NULL, NULL, NULL ) == -1 ) | |||
{ | |||
perror( "select()" ); | |||
/* error */ | |||
} | |||
/* service connections */ | |||
/* FIXME: there's a better way to do this than cover *all* fds. */ | |||
for ( int i = 2; i < maxfd + 1; ++i ) | |||
{ | |||
if ( FD_ISSET( i, &read_fds ) ) | |||
{ | |||
if ( i == server ) | |||
{ | |||
struct sockaddr_in ca; | |||
socklen_t al = sizeof( ca ); | |||
int c; | |||
if ( ( c = accept( server, (struct sockaddr *)&ca, &al ) ) < 0 ) | |||
perror( "accept()" ); | |||
FD_SET( c, &master ); | |||
if ( c > maxfd ) | |||
maxfd = c; | |||
handle_new( c ); | |||
// printf( "New connection from %s on socket %d\n", inet_ntoa( ca.sin_addr ), c ); | |||
} | |||
else | |||
{ | |||
char buf[ BUFSIZ ]; | |||
int l; | |||
if ( ( l = recv( i, buf, sizeof( buf ), 0 ) ) <= 0 ) | |||
{ | |||
if ( l == 0 ) | |||
{ | |||
handle_hang_up( i ); | |||
} | |||
else | |||
perror( "recv()" ); | |||
close( i ); | |||
FD_CLR( i, &master ); | |||
} | |||
else | |||
{ | |||
/* echo to others */ | |||
for ( int j = maxfd; j-- ; ) | |||
{ | |||
if ( ! FD_ISSET( j, &master ) ) | |||
continue; | |||
if ( j != server && j != i ) | |||
{ | |||
if ( send( j, buf, l, 0 ) < 0 ) | |||
perror( "send()" ); | |||
} | |||
} | |||
buf[ l ] = '\0'; | |||
handle_request( buf, l ); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
/*******************************************************************************/ | |||
/* 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. */ | |||
/*******************************************************************************/ | |||
class Server | |||
{ | |||
int _port; | |||
static int listen_on_port ( int port ); | |||
public: | |||
Server ( int port ); | |||
void run ( void ); | |||
protected: | |||
virtual void handle_hang_up ( int s ) = 0; | |||
virtual void handle_new ( int s ) = 0; | |||
virtual void handle_request ( const char *s, int l ) = 0; | |||
}; |
@@ -0,0 +1,71 @@ | |||
/*******************************************************************************/ | |||
/* 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. */ | |||
/*******************************************************************************/ | |||
// #include "objects.H" | |||
/* #include <sys/socket.h> */ | |||
/* #include <sys/types.h> */ | |||
/* #include <sys/select.h> */ | |||
#include "Timeline_Server.H" | |||
#include <stdio.h> | |||
/* Timeline Server. | |||
The timeline server runs in its own thread and manages communication | |||
between the engine and any connected timeline editors. | |||
Its duties are as follows: | |||
* Listen for connections from Timeline Editors on a TCP port. | |||
* Accept 'do' messages from each connection, echoing the change to | |||
all others. | |||
* Keep global engine state in sync with recieved messages (in a | |||
lock-free manner) | |||
* Write do+undo messages to journal. | |||
* Translate "undo" command into the appropriate 'do' messages. | |||
*/ | |||
#define TIMELINE_PORT 6100 | |||
void | |||
Timeline_Server::handle_new ( int s ) | |||
{ | |||
printf( "new connection\n" ); | |||
} | |||
void | |||
Timeline_Server::handle_hang_up ( int s ) | |||
{ | |||
printf( "hangup\n" ); | |||
} | |||
void | |||
Timeline_Server::handle_request ( const char *s, int l ) | |||
{ | |||
printf( "request: %s", s ); | |||
} |
@@ -0,0 +1,38 @@ | |||
/*******************************************************************************/ | |||
/* 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 Timeline_Server : public Server | |||
{ | |||
protected: | |||
void handle_new ( int s ); | |||
void handle_hang_up ( int s ); | |||
void handle_request ( const char *s, int l ); | |||
public: | |||
Timeline_Server ( int port ) : Server ( port ) | |||
{ | |||
} | |||
}; |
@@ -0,0 +1,66 @@ | |||
/*******************************************************************************/ | |||
/* 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. */ | |||
/*******************************************************************************/ | |||
#include "const.h" | |||
#include "Audio_File.H" | |||
#include "Peaks.H" | |||
#include "Loggable.H" | |||
#include "Timeline_Server.H" | |||
/* TODO: | |||
Run server process here. | |||
* Manage session file. | |||
* Keep state for all relevant objects (must mirror that in Timeline) | |||
* Listen for incoming connections. | |||
* Send and recieve 'do' messages to client(s), recording do and undo portions to journal. Serve peaks (maybe in a separate process?) | |||
Peak request looks like: | |||
> read_peaks "foo.wav" fpp start end | |||
Response looks like (in binary floats): | |||
> length min max min max min max | |||
State must be communicated to realtime thread locklessly so that: | |||
Realtime: | |||
* Manage JACK transport. | |||
* Manage JACK outputs. | |||
* Stream regions from disk. | |||
* Manage JACK inputs. | |||
* Stream tracks to disk when recording. | |||
* Stream control points as OSC messages. (RT safe?) | |||
*/ | |||
int | |||
main ( int argc, char **argv ) | |||
{ | |||
Timeline_Server tls( 6110 ); | |||
tls.run(); | |||
} |
@@ -5,6 +5,7 @@ LIBS := -lsndfile `fltk-config --ldflags` | |||
all: all | |||
%: | |||
@ $(MAKE) -s -C Engine CXXFLAGS="$(CXXFLAGS)" LIBS="$(LIBS)" $@ | |||
@ $(MAKE) -s -C FL CXXFLAGS="$(CXXFLAGS)" LIBS="$(LIBS)" $@ | |||
@ $(MAKE) -s -C Timeline CXXFLAGS="$(CXXFLAGS)" LIBS="$(LIBS)" $@ | |||
@ $(MAKE) -s -C Mixer CXXFLAGS="$(CXXFLAGS)" LIBS="$(LIBS)" $@ |