Version 3.0

This commit is contained in:
Gary Scavone
2013-09-25 11:21:51 +02:00
committed by Stephen Sinclair
parent 7c0ee03d60
commit 868787a5f9
348 changed files with 12471 additions and 9135 deletions

View File

@@ -1 +1 @@
wish < tcl/TwoWaves.tcl | MUS151 TwoOsc -r
wish < tcl/TwoWaves.tcl | MUS151 TwoOsc -ip

View File

@@ -2,261 +2,68 @@
/******** Center for Computer Research in Music & Acoustics ******/
/******** Stanford University, by Gary P. Scavone, 1998 **********/
#include "../miditabl.h"
#include "../WvOut.h"
#include "../RTWvOut.h"
#include "../SKINI11.h"
#include "../STK/WvOut.h"
#include "../STK/RTWvOut.h"
#include "../STK/SKINI11.h"
#include "../STK/SKINI11.msg"
#include "TwoOsc.h"
#include "../SKINI11.msg"
#define INSTR_LEN 60
#include "miditabl.h"
int numStrings = 0;
int notDone = 1;
char **inputString;
#if defined(__SGI_REALTIME_)
#include <sys/types.h>
#include <sys/prctl.h>
#include <signal.h>
char inputString[MAX_IN_STRINGS][INSTR_LEN];
pid_t string_thread;
void newString(void *)
{
int inOne = 0;
while (notDone) {
fgets(inputString[inOne],INSTR_LEN,stdin);
if (inputString[inOne][0] == 'E' && inputString[inOne][1] == 'x') {
notDone = 0;
}
else {
numStrings++;
if (numStrings > MAX_IN_STRINGS) {
fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n");
numStrings--;
}
inOne++;
if (inOne == MAX_IN_STRINGS) inOne = 0;
}
}
}
#elif defined(__USS_REALTIME_)
#include <pthread.h>
//#include <pthread/mit/pthread.h>
char inputString[MAX_IN_STRINGS][INSTR_LEN];
pthread_t string_thread;
void *newString(void *)
{
int inOne = 0;
while (notDone) {
fgets(inputString[inOne],INSTR_LEN,stdin);
if (inputString[inOne][0] == 'E' && inputString[inOne][1] == 'x') {
notDone = 0;
}
else {
numStrings++;
if (numStrings > MAX_IN_STRINGS) {
fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n");
numStrings--;
}
inOne++;
if (inOne == MAX_IN_STRINGS) inOne = 0;
}
}
}
#elif (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) )
#include <process.h>
#include <winsock.h>
char inputString[MAX_IN_STRINGS][INSTR_LEN];
unsigned long string_thread;
#define SERVICE_PORT 2001
void newString(void *)
{
int inOne = 0, i=0, m=0, n;
SOCKET soc_id, accept_id;
WSADATA wsaData;
int nRet;
struct sockaddr_in sockname;
WORD wVersionRequested = MAKEWORD(1,1);
char socBuf[INSTR_LEN];
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
exit(0);
}
/* Create the server-side socket */
soc_id = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(soc_id == INVALID_SOCKET) {
fprintf(stderr,"Couldn't create socket!\n");
exit(0);
}
sockname.sin_family=AF_INET;
sockname.sin_addr.s_addr=INADDR_ANY;
sockname.sin_port=htons(SERVICE_PORT);
/* Bind socket to the appropriate port and interface (INADDR_ANY) */
if (bind(soc_id,(LPSOCKADDR)&sockname,sizeof(sockname))==SOCKET_ERROR) {
fprintf(stderr,"Couldn't bind socket!\n");
exit(0);
}
/* Listen for incoming connections */
printf("Listening for socket on port %d\n", SERVICE_PORT);
if (listen(soc_id,1)==SOCKET_ERROR) {
fprintf(stderr,"Couldn't set up listen on socket!\n");
exit(0);
}
/* Accept and service one incoming connection request */
accept_id=accept(soc_id,NULL,NULL);
if (accept_id==INVALID_SOCKET) {
fprintf(stderr,"Couldn't accept incoming connection on socket!\n");
exit(0);
}
memset(socBuf, 0, sizeof(socBuf));
printf("Socket connection made ... ready to receive SKINI messages.\n");
while (notDone) {
i = recv(accept_id, socBuf, INSTR_LEN, 0);
if (i==0) notDone = 0;
n = 0;
while (n < i) {
inputString[inOne][m++] = socBuf[n];
if (socBuf[n++] == '\n') {
if (inputString[inOne][0] == 'E' && inputString[inOne][1] == 'x') {
notDone = 0;
n = i;
}
else {
m = 0;
numStrings++;
if (numStrings > MAX_IN_STRINGS) {
fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n");
numStrings--;
}
inOne++;
if (inOne == MAX_IN_STRINGS) inOne = 0;
}
memset(inputString[inOne], 0, INSTR_LEN);
}
}
}
closesocket(accept_id);
closesocket(soc_id);
WSACleanup();
printf("Socket connection closed.\n");
}
#else
char inputString[1][INSTR_LEN];
#endif
// The input command pipe and socket threads are defined in threads.cpp.
#include "threads.h"
/* Error function in case of incorrect command-line argument specifications */
void errorf(char *func) {
printf("\nuseage: %s Instr \n",func);
printf(" where Instr = TwoOsc (only one available for now)\n\n");
printf("\nuseage: %s Instr flag\n",func);
printf(" where Instr = TwoOsc (only one available for now)\n");
printf(" and flag = -ip for realtime SKINI input by pipe\n");
printf(" (won't work under Win95/98),\n");
printf(" or flag = -is for realtime SKINI input by socket.\n");
exit(0);
}
void main(int argc,char *argv[])
{
long i, j, synlength;
long i, j, synlength, useSocket = 0;
int type, rtInput = 0;
int outOne = 0;
char *fin;
MY_FLOAT settleTime = 0.5; /* in seconds */
MY_FLOAT temp, byte3, lastPitch;
WvOut *output;
TwoOsc *instrument;
SKINI11 *score;
if (argc > 1) {
if (!strcmp(argv[1],"TwoOsc")) instrument = new TwoOsc;
else errorf(argv[0]);
if (argc == 3) {
if (strcmp(argv[1],"TwoOsc")) errorf(argv[0]);
if (!strcmp(argv[2],"-is")) useSocket = 1;
else if (strcmp(argv[2],"-ip")) errorf(argv[0]);
} else errorf(argv[0]);
output = new RTWvOut();
score = new SKINI11();
TwoOsc *instrument = new TwoOsc;
WvOut *output = new RTWvOut(SRATE,1);
SKINI11 *score = new SKINI11();
rtInput = 1; /* We're going to always use realtime input */
// Start the input thread.
if (useSocket)
startSocketThread();
else
startPipeThread();
instrument->noteOn(200.0,0.1);
/* If using realtime input, setup the input thread. */
#if defined(__SGI_REALTIME_)
if (rtInput) {
string_thread = sproc(newString, PR_SALL);
if (string_thread == -1) {
fprintf(stderr, "unable to create input thread...aborting.\n");
exit(-1);
}
instrument->noteOn(200.0, 0.2);
}
#elif defined(__USS_REALTIME_)
if (rtInput) {
if (pthread_create(&string_thread, NULL, newString, NULL))
{
fprintf(stderr, "unable to create input thread...aborting.\n");
exit(-1);
}
instrument->noteOn(200.0,0.2);
}
#elif (defined(__WINDS_REALTIME_) || defined(__WINMM_REALTIME_) )
if (rtInput) {
string_thread = _beginthread(newString, 0, NULL);
if (string_thread == -1) {
fprintf(stderr, "Unable to create exit thread.\n");
printf("Exiting MD2SKINI process.\n");
exit(0);
}
instrument->noteOn(200.0,0.2);
}
#endif
/* Finally ... the runtime loop begins! */
// The runtime loop begins here:
notDone = 1;
synlength = RT_BUFFER_SIZE;
while(notDone || numStrings) {
if (rtInput) {
if (numStrings > 1) synlength = (long) RT_BUFFER_SIZE / numStrings;
else synlength = RT_BUFFER_SIZE;
for ( i=0; i<synlength; i++ ) {
output->tick(instrument->tick());
}
}
else {
fin = fgets(inputString[0],INSTR_LEN,stdin);
if (fin == NULL) notDone = 0;
else {
numStrings++;
}
if (numStrings > 1) synlength = (long) RT_BUFFER_SIZE / numStrings;
else synlength = RT_BUFFER_SIZE;
for ( i=0; i<synlength; i++ ) {
output->tick(instrument->tick());
}
if (numStrings) {
score->parseThis(inputString[outOne]);
type = score->getType();
if (type > 0) {
if (temp = score->getDelta()) { /* SKINI score file */
synlength = (long) (temp * SRATE);
for ( i=0; i<synlength; i++ ) {
output->tick(instrument->tick());
}
synlength = 0;
}
if (type == __SK_NoteOn_ ) {
if (( byte3 = score->getByteThree() ) == 0)
instrument->noteOff(byte3*NORM_7);
@@ -290,10 +97,8 @@ void main(int argc,char *argv[])
else if (type == __SK_ProgramChange_) {
}
}
if (rtInput) {
outOne += 1;
if (outOne == MAX_IN_STRINGS) outOne = 0;
}
outOne += 1;
if (outOne == MAX_IN_STRINGS) outOne = 0;
numStrings--;
}
}
@@ -305,8 +110,5 @@ void main(int argc,char *argv[])
delete score;
delete instrument;
#if defined(__SGI_REALTIME_)
if (rtInput) kill(string_thread, SIGKILL);
#endif
printf("MUS151 finished.\n");
}

View File

@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -65,7 +65,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__OS_Win_" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -83,11 +83,11 @@ LINK32=link.exe
# Name "MUS151 - Win32 Debug"
# Begin Source File
SOURCE=..\Envelope.cpp
SOURCE=..\Stk\Envelope.cpp
# End Source File
# Begin Source File
SOURCE=..\Envelope.h
SOURCE=..\Stk\Envelope.h
# End Source File
# Begin Source File
@@ -95,51 +95,43 @@ SOURCE=.\MUS151.cpp
# End Source File
# Begin Source File
SOURCE=..\Object.cpp
SOURCE=..\Stk\Object.cpp
# End Source File
# Begin Source File
SOURCE=..\Object.h
SOURCE=..\Stk\Object.h
# End Source File
# Begin Source File
SOURCE=..\RawLoop.cpp
SOURCE=..\Stk\RawWvIn.cpp
# End Source File
# Begin Source File
SOURCE=..\RawLoop.h
SOURCE=..\Stk\RawWvIn.h
# End Source File
# Begin Source File
SOURCE=..\RawWave.cpp
SOURCE=..\Stk\RTSoundIO.cpp
# End Source File
# Begin Source File
SOURCE=..\RawWave.h
SOURCE=..\Stk\RTSoundIO.h
# End Source File
# Begin Source File
SOURCE=..\RTSoundIO.cpp
SOURCE=..\Stk\RTWvOut.cpp
# End Source File
# Begin Source File
SOURCE=..\RTSoundIO.h
SOURCE=..\Stk\RTWvOut.h
# End Source File
# Begin Source File
SOURCE=..\RTWvOut.cpp
SOURCE=..\Stk\SKINI11.cpp
# End Source File
# Begin Source File
SOURCE=..\RTWvOut.h
# End Source File
# Begin Source File
SOURCE=..\SKINI11.cpp
# End Source File
# Begin Source File
SOURCE=..\SKINI11.h
SOURCE=..\Stk\SKINI11.h
# End Source File
# Begin Source File
@@ -151,11 +143,19 @@ SOURCE=..\SKINI11.tbl
# End Source File
# Begin Source File
SOURCE=..\swapstuf.cpp
SOURCE=..\Stk\swapstuf.cpp
# End Source File
# Begin Source File
SOURCE=..\swapstuf.h
SOURCE=..\Stk\swapstuf.h
# End Source File
# Begin Source File
SOURCE=.\threads.cpp
# End Source File
# Begin Source File
SOURCE=.\threads.h
# End Source File
# Begin Source File
@@ -167,11 +167,19 @@ SOURCE=.\TwoOsc.h
# End Source File
# Begin Source File
SOURCE=..\WvOut.cpp
SOURCE=..\Stk\WvIn.cpp
# End Source File
# Begin Source File
SOURCE=..\WvOut.h
SOURCE=..\Stk\WvIn.h
# End Source File
# Begin Source File
SOURCE=..\Stk\WvOut.cpp
# End Source File
# Begin Source File
SOURCE=..\Stk\WvOut.h
# End Source File
# End Target
# End Project

Binary file not shown.

BIN
mus151/MUS151.opt Normal file

Binary file not shown.

View File

@@ -1,11 +1,8 @@
# MUS151 Makefile - Global version for Unix systems which have GNU
# Makefile utilities installed.
#
# This is an example project Makefile, to demonstrate how one might
# develop an STK project that resides apart from the core STK
# distribution. It is highly recommended that you keep your
# personal STK projects separate from the core distribution, to
# make upgrading to newer releases more simple.
# Makefile utilities installed. If you do not have the GNU Makefile
# utilities, I suggest you download them. If that is not possible,
# look at syntmono/Makefile.sgi to see what has to be done to get
# things to compile.
#
# by Gary P. Scavone
# CCRMA, Stanford University, 1998.
@@ -16,27 +13,26 @@ OS = $(shell uname)
# location in your system. The following definition corresponds
# to an STK project directory that is a subdirectory of the core
# STK distribution.
STK_PATH = ../
STK_PATH = ../STK/
O_FILES = Object.o Envelope.o RawWave.o RawLoop.o \
O_FILES = Object.o Envelope.o WvIn.o RawWvIn.o \
SKINI11.o swapstuf.o WvOut.o \
RTWvOut.o RTSoundIO.o \
\
TwoOsc.o
TwoOsc.o threads.o
RM = /bin/rm
ifeq ($(OS),IRIX) # These are for SGI
INSTR = MUS151
CC = CC -O # -g -fullwarn -D__SGI_CC__
CC = CC -O2 -D__OS_IRIX_ # -g -fullwarn -D__SGI_CC__
LIBRARY = -L/usr/sgitcl/lib -laudio -lmd -lm
endif
ifeq ($(OS),Linux) # These are for Linux
INSTR = MUS151
CC = gcc -O3 # -g -pg -O3
CC = g++ -O3 -D__OS_Linux_ # -g
LIBRARY = -lpthread -lm
# LIBRARY = /lib/libpthread.so.0 -lm
endif
%.o : $(STK_PATH)%.cpp
@@ -50,6 +46,9 @@ MUS151: MUS151.cpp $(O_FILES)
TwoOsc.o : TwoOsc.cpp
$(CC) -c TwoOsc.cpp
threads.o : threads.cpp
$(CC) -c threads.cpp
all: $(INSTR)
clean :

View File

@@ -1,15 +1,21 @@
STK: A ToolKit of Audio Synthesis Classes and Instruments in C++
Version 3.0
By Perry R. Cook, 1995-99
and Gary P. Scavone, 1997-99.
MUS151: An example project using STK
By Gary P. Scavone
CCRMA, Stanford University, 1998.
CCRMA, Stanford University, 1999.
It is highly recommended that you keep your personal STK projects separate from the STK core distribution, to make upgrading to newer releases more simple. The files in this directory demonstrate how one might manage this.
This directory contains a simple two-oscillator program that can be used to demonstrate psychoacoustic masking effects. It is highly recommended that you keep your personal STK projects separate from the STK core distribution, to make upgrading to newer releases more simple. The files in this directory demonstrate how one might manage this.
This simple project, named MUS151 for the pyschoacoustics class taught at CCRMA, plays two sine waves and allows independent control of their amplitudes and frequencies. The file MUS151.cpp is essentially the same as syntmono.cpp, though simplified to a great extent because of its more specific use. In particular, only one "instrument" is currently supported (TwoOsc) and only real-time output is used (thus, this project cannot be compiled for NeXTStep). A simple Tcl/Tk GUI has been created to control the instrument. The GUI and STK project can be run under Linux and SGI using the simple GUITwoOsc executable script.
The mus151 project directory has been distributed as a subdirectory of the core STK file directory. In this location, the project should compile without any problems (on Linux, SGI, and Win platforms). Should you choose to relocate this directory, several path variables will need to be updated as described below.
The mus151 project directory has been distributed as a separate directory from the core STK file directory. In this location, the project should compile without any problems (on Linux, SGI, and Win platforms). Should you choose to relocate this directory, several path variables will need to be updated as described below.
Three "personal" STK files were created for this project: MUS151.cpp and the TwoOsc class files TwoOsc.h and TwoOsc.cpp. A specific Tcl/Tk GUI script was written (TwoOsc.tcl) and is located in the "tcl" subdirectory. Depending on where you choose to locate the mus151 directory, several #include statements may need to be updated to reflect the location of the STK core distribution. For example, mus151/ is currently a subdirectory of the STK core files, so the various core STK header files are referenced in TwoOsc.h as: #include "../Instrmnt.h". You could move the mus151 files to a completely different point on your directory tree, but you would have to update those statements to correctly reference your core files. Likewise, the "sinewave.raw" file must be correctly referenced in TwoOsc.cpp.
Three "personal" STK files were created for this project: MUS151.cpp and the TwoOsc class files TwoOsc.h and TwoOsc.cpp. A specific Tcl/Tk GUI script was written (TwoOsc.tcl) and is located in the "tcl" subdirectory. Depending on where you choose to locate the mus151 directory, several #include statements may need to be updated to reflect the location of the STK core distribution. For example, mus151/ is currently outside the STK core files directory, so the various core STK header files are referenced in TwoOsc.h as: #include "../STK/Instrmnt.h". You could move the mus151 files to a completely different point on your directory tree, but you would have to update those statements to correctly reference your core files. Likewise, the RAWWAVE_PATH define statement in Object.h must be properly set for the "sinewave.raw" file to be correctly referenced in TwoOsc.cpp.
The unix Makefile must also be updated to correctly reference the STK core distribution. A variable, STK_PATH, has been created to simplify this procedure. Note that all STK core object files are referenced with a single, general statement. All personal object files need their own dependency definitions.

View File

@@ -13,8 +13,12 @@ TwoOsc :: TwoOsc()
envelope = new Envelope; /* Envelope to avoid clicks */
// Concatenate the STK RAWWAVE_PATH to the rawwave file
char file[128];
strcpy(file, RAWWAVE_PATH);
for (i=0; i<2; i++) {
osc[i] = new RawLoop("../rawwaves/sinewave.raw");
osc[i] = new RawWvIn(strcat(file,"rawwaves/sinewave.raw"),"looping");
strcpy(file, RAWWAVE_PATH);
osc[i]->normalize();
osc[i]->setFreq((MY_FLOAT) 200.0);
amps[i] = 0.2;

View File

@@ -8,16 +8,14 @@
#if !defined(__TwoOsc_h)
#define __TwoOsc_h
//#include "../Instrmnt.h"
#include "../Envelope.h"
#include "../RawLoop.h"
#include "../STK/Envelope.h"
#include "../STK/RawWvIn.h"
class TwoOsc : public Object
{
protected:
Envelope *envelope;
RawLoop *osc[2];
RawWvIn *osc[2];
MY_FLOAT lastOutput;
MY_FLOAT amps[2];

19
mus151/miditabl.h Normal file
View File

@@ -0,0 +1,19 @@
#include "../STK/Object.h"
double __MIDI_To_Pitch[128] = {
8.18,8.66,9.18,9.72,10.30,10.91,11.56,12.25,
12.98,13.75,14.57,15.43,16.35,17.32,18.35,19.45,
20.60,21.83,23.12,24.50,25.96,27.50,29.14,30.87,
32.70,34.65,36.71,38.89,41.20,43.65,46.25,49.00,
51.91,55.00,58.27,61.74,65.41,69.30,73.42,77.78,
82.41,87.31,92.50,98.00,103.83,110.00,116.54,123.47,
130.81,138.59,146.83,155.56,164.81,174.61,185.00,196.00,
207.65,220.00,233.08,246.94,261.63,277.18,293.66,311.13,
329.63,349.23,369.99,392.00,415.30,440.00,466.16,493.88,
523.25,554.37,587.33,622.25,659.26,698.46,739.99,783.99,
830.61,880.00,932.33,987.77,1046.50,1108.73,1174.66,1244.51,
1318.51,1396.91,1479.98,1567.98,1661.22,1760.00,1864.66,1975.53,
2093.00,2217.46,2349.32,2489.02,2637.02,2793.83,2959.96,3135.96,
3322.44,3520.00,3729.31,3951.07,4186.01,4434.92,4698.64,4978.03,
5274.04,5587.65,5919.91,6271.93,6644.88,7040.00,7458.62,7902.13,
8372.02,8869.84,9397.27,9956.06,10548.08,11175.30,11839.82,12543.85};

View File

@@ -1,3 +1,7 @@
# Tcl/Tk Demo GUI for the Synthesis Toolkit (STK)
# by Gary P. Scavone, CCRMA, Stanford University, 1999.
# Set initial control values
set pitch 64.0
set osc1on 1
set osc2on 1
@@ -93,6 +97,9 @@ checkbutton .onOff.2 -text "Play Osc 2" -variable osc2on -relief flat \
pack .onOff.1 .onOff.2 -padx 5
pack .onOff -side right -padx 5 -pady 10
# Bind an X windows "close" event with the Exit routine
bind . <Destroy> +myExit
proc myExit {} {
global outID
puts $outID [format "NoteOff 0.0 1 64 127" ]
@@ -149,7 +156,9 @@ proc setPlayStatus {controlNum value } {
set d .socketdialog
proc setComm {} {
global outID commtype d
global outID
global commtype
global d
if {$commtype == "stdout"} {
if { [string compare "stdout" $outID] } {
set i [tk_dialog .dialog "Break Socket Connection?" {You are about to break an existing socket connection ... is this what you want to do?} "" 0 Cancel OK]
@@ -161,21 +170,30 @@ proc setComm {} {
}
} elseif { ![string compare "stdout" $outID] } {
set sockport 2001
set sockhost localhost
toplevel $d
wm title $d "STK Client Socket Connection"
wm resizable $d 0 0
grab $d
label $d.message -text "Specify a socket port number below (if different than the STK default of 2001) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
label $d.message -text "Specify a socket host and port number below (if different than the STK defaults shown) and then click the \"Connect\" button to invoke a socket-client connection attempt to the STK socket server." \
-background white -font {Helvetica 10 bold} \
-wraplength 3i -justify left
frame $d.sockhost
entry $d.sockhost.entry -width 15
label $d.sockhost.text -text "Socket Host:" \
-font {Helvetica 10 bold}
frame $d.sockport
entry $d.sockport.entry -width 6
label $d.sockport.text -text "Socket Port Number:" \
entry $d.sockport.entry -width 15
label $d.sockport.text -text "Socket Port:" \
-font {Helvetica 10 bold}
pack $d.message -side top -padx 5 -pady 10
pack $d.sockport.text -side left -padx 1 -pady 10
pack $d.sockport.entry -side right -padx 5 -pady 10
pack $d.sockport -side top -padx 5 -pady 10
pack $d.sockhost.text -side left -padx 1 -pady 2
pack $d.sockhost.entry -side right -padx 5 -pady 2
pack $d.sockhost -side top -padx 5 -pady 2
pack $d.sockport.text -side left -padx 1 -pady 2
pack $d.sockport.entry -side right -padx 5 -pady 2
pack $d.sockport -side top -padx 5 -pady 2
$d.sockhost.entry insert 0 $sockhost
$d.sockport.entry insert 0 $sockport
frame $d.buttons
button $d.buttons.cancel -text "Cancel" -bg grey66 \
@@ -184,8 +202,10 @@ proc setComm {} {
destroy $d }
button $d.buttons.connect -text "Connect" -bg grey66 \
-command {
set sockhost [$d.sockhost.entry get]
set sockport [$d.sockport.entry get]
set err [catch {socket localhost $sockport} outID]
set err [catch {socket $sockhost $sockport} outID]
if {$err == 0} {
destroy $d
} else {

282
mus151/threads.cpp Normal file
View File

@@ -0,0 +1,282 @@
// Thread functions for use with syntmono.
//
// Gary P. Scavone, 1999.
#include "threads.h"
#if defined(__STK_REALTIME_)
#define SERVICE_PORT 2001 // Socket Port ID number
// Do OS dependent declarations and includes
#if defined(__OS_IRIX_)
#include <signal.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>
pid_t string_thread;
#elif defined(__OS_Linux_)
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <unistd.h>
pthread_t string_thread;
#elif defined(__OS_Win_)
#include <process.h>
#include <winsock.h>
unsigned long string_thread;
#endif
// The thread function definition protocols are slightly
// different under Irix, Linux, and Windoze.
#if defined(__OS_IRIX_)
void newStringByPipe(void *)
#elif defined(__OS_Linux_)
void *newStringByPipe(void *)
#elif defined(__OS_Win_)
void newStringByPipe(void *)
#endif
{
extern int numStrings, notDone;
extern char **inputString;
int i;
// Malloc inputString.
inputString = (char **) malloc(MAX_IN_STRINGS * sizeof(char *));
for ( i=0;i<MAX_IN_STRINGS;i++ )
inputString[i] = (char *) malloc(STRING_LEN * sizeof(char));
int inOne = 0;
while (notDone) {
fgets(inputString[inOne],STRING_LEN,stdin);
if (inputString[inOne][2] == 'i' && inputString[inOne][3] == 't'
&& inputString[inOne][1] == 'x' && inputString[inOne][0] == 'E') {
notDone = 0;
}
else {
numStrings++;
if (numStrings > MAX_IN_STRINGS) {
fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n");
numStrings--;
}
inOne++;
if (inOne == MAX_IN_STRINGS) inOne = 0;
}
}
// Free inputString.
for ( i=0;i<MAX_IN_STRINGS;i++ ) free(inputString[i]);
free(inputString);
}
#if defined(__OS_IRIX_)
void newStringBySocket(void *)
#elif defined(__OS_Linux_)
void *newStringBySocket(void *)
#elif defined(__OS_Win_)
void newStringBySocket(void *)
#endif
{
extern int numStrings, notDone;
extern char **inputString;
int inOne = 0, i=0, m=0, n, parsing;
int soc_id, accept_id;
int maxfd, fd;
fd_set mask, rmask;
struct sockaddr_in sockname;
char socBuf[STRING_LEN];
static struct timeval timeout = {0, 1000}; // one millisecond
// Malloc inputString.
inputString = (char **) malloc(MAX_IN_STRINGS * sizeof(char *));
for ( i=0;i<MAX_IN_STRINGS;i++ )
inputString[i] = (char *) malloc(STRING_LEN * sizeof(char));
memset(socBuf, 0, sizeof(socBuf));
#if defined(__OS_Win_) // Stupid Windoze only stuff
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(1,1);
int nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested) {
fprintf(stderr,"\n Wrong Windoze socket library version!\n");
exit(0);
}
#endif
// Create the server-side socket
soc_id = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(soc_id < 0) {
fprintf(stderr,"Couldn't create socket ... aborting!\n");
exit(0);
}
sockname.sin_family=AF_INET;
sockname.sin_addr.s_addr=INADDR_ANY;
sockname.sin_port=htons(SERVICE_PORT);
/* Bind socket to the appropriate port and interface (INADDR_ANY) */
if (bind(soc_id,(struct sockaddr *)&sockname,sizeof(sockname)) < 0) {
fprintf(stderr,"Couldn't bind socket ... aborting!\n");
exit(0);
}
/* Listen for incoming connections */
printf("Listening for socket connections on port %d\n", SERVICE_PORT);
if (listen(soc_id,SOMAXCONN) < 0) {
fprintf(stderr,"Couldn't set up listen on socket ... aborting!\n");
exit(0);
}
FD_ZERO(&mask);
FD_SET(soc_id, &mask);
maxfd = soc_id;
while (notDone) {
rmask = mask;
select(maxfd+1, &rmask, (fd_set *)0, (fd_set *)0, &timeout);
if (FD_ISSET(soc_id,&rmask)) { // a new connection is available
// Accept and service the incoming connection request
accept_id=accept(soc_id,NULL,NULL);
if (accept_id < 0) {
fprintf(stderr,"Couldn't accept incoming connection on socket ... aborting!\n");
exit(0);
}
printf("New socket connection made ... ready to receive SKINI messages.\n");
FD_SET(accept_id, &mask);
if (accept_id > maxfd) maxfd = accept_id;
FD_CLR(soc_id, &rmask);
}
for (fd=0;fd<=maxfd;fd++) { // look for other sockets with data
if (FD_ISSET(fd, &rmask)) { // process the data
parsing = 1;
while (parsing) {
i = recv(fd, socBuf, STRING_LEN,0);
if (i==0) {
printf("Closing a socket connection.\n");
FD_CLR(fd, &mask);
#if defined(__OS_Win_)
closesocket(fd);
#else
close(fd);
#endif
parsing = 0;
}
n = 0;
while (n < i) {
inputString[inOne][m++] = socBuf[n];
if (socBuf[n++] == '\n') {
if (inputString[inOne][2] == 'i' && inputString[inOne][3] == 't'
&& inputString[inOne][1] == 'x' && inputString[inOne][0] == 'E') {
notDone = 0;
n = i;
parsing = 0;
}
else {
m = 0;
if (n >= i) parsing = 0;
numStrings++;
if (numStrings > MAX_IN_STRINGS) {
fprintf(stderr,"Losing MIDI data ... try increasing MAX_IN_STRINGS.\n");
numStrings--;
}
inOne++;
if (inOne == MAX_IN_STRINGS) inOne = 0;
memset(inputString[inOne], 0, STRING_LEN);
}
}
}
}
}
}
}
#if defined(__OS_Win_) // Stupid Windoze only stuff
closesocket(soc_id);
WSACleanup();
#else
shutdown(soc_id,0);
#endif
// Free inputString.
for ( i=0;i<MAX_IN_STRINGS;i++ ) free(inputString[i]);
free(inputString);
printf("Socket connection closed.\n");
}
void startPipeThread()
{
#if defined(__OS_IRIX_)
string_thread = sproc(newStringByPipe, PR_SALL);
if (string_thread == -1) {
fprintf(stderr, "unable to create input pipe thread ... aborting.\n");
exit(0);
}
#elif defined(__OS_Linux_)
if (pthread_create(&string_thread, NULL, newStringByPipe, NULL)) {
fprintf(stderr, "unable to create input pipe thread ... aborting.\n");
exit(0);
}
#elif defined(__OS_Win_)
string_thread = _beginthread(newStringByPipe, 0, NULL);
if (string_thread == -1) {
fprintf(stderr, "unable to create input pipe thread ... aborting.\n");
exit(0);
}
#endif
}
void startSocketThread()
{
#if defined(__OS_IRIX_)
string_thread = sproc(newStringBySocket, PR_SALL);
if (string_thread == -1) {
fprintf(stderr, "unable to create input socket thread...aborting.\n");
exit(0);
}
#elif defined(__OS_Linux_)
if (pthread_create(&string_thread, NULL, newStringBySocket, NULL)) {
fprintf(stderr, "unable to create input socket thread...aborting.\n");
exit(0);
}
#elif defined(__OS_Win_)
string_thread = _beginthread(newStringBySocket, 0, NULL);
if (string_thread == -1) {
fprintf(stderr, "unable to create input socket thread...aborting.\n");
exit(0);
}
#endif
}
#endif

27
mus151/threads.h Normal file
View File

@@ -0,0 +1,27 @@
// Thread functions for use with syntmono.
//
// Gary P. Scavone, 1999.
#include "../STK/Object.h"
#define STRING_LEN 60
#if (defined(__STK_REALTIME_) && defined(__OS_IRIX_) )
void newStringByPipe(void *);
void newStringBySocket(void *);
#elif (defined(__STK_REALTIME_) && defined(__OS_Linux_) )
void *newStringByPipe(void *);
void *newStringBySocket(void *);
#elif (defined(__STK_REALTIME_) && defined(__OS_Win_) )
void newStringByPipe(void *);
void newStringBySocket(void *);
#endif
void startPipeThread();
void startSocketThread();