mirror of
https://github.com/thestk/stk
synced 2026-05-03 20:38:12 +00:00
Version 2.02
This commit is contained in:
committed by
Stephen Sinclair
parent
ea749b71d2
commit
7c0ee03d60
0
mus151/Debug/.placeholder
Normal file
0
mus151/Debug/.placeholder
Normal file
1
mus151/GUITwoOsc
Executable file
1
mus151/GUITwoOsc
Executable file
@@ -0,0 +1 @@
|
||||
wish < tcl/TwoWaves.tcl | MUS151 TwoOsc -r
|
||||
312
mus151/MUS151.cpp
Normal file
312
mus151/MUS151.cpp
Normal file
@@ -0,0 +1,312 @@
|
||||
/******** Psychoacoustic Interface Program for MUS151 ************/
|
||||
/******** 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 "TwoOsc.h"
|
||||
|
||||
#include "../SKINI11.msg"
|
||||
|
||||
#define INSTR_LEN 60
|
||||
|
||||
int numStrings = 0;
|
||||
int notDone = 1;
|
||||
|
||||
#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
|
||||
|
||||
/* 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");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void main(int argc,char *argv[])
|
||||
{
|
||||
long i, j, synlength;
|
||||
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]);
|
||||
} else errorf(argv[0]);
|
||||
|
||||
output = new RTWvOut();
|
||||
score = new SKINI11();
|
||||
|
||||
rtInput = 1; /* We're going to always use realtime input */
|
||||
|
||||
/* 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! */
|
||||
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) {
|
||||
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);
|
||||
else {
|
||||
j = (int) score->getByteTwo();
|
||||
temp = __MIDI_To_Pitch[j];
|
||||
lastPitch = temp;
|
||||
instrument->noteOn(temp,byte3*NORM_7);
|
||||
}
|
||||
}
|
||||
else if (type == __SK_NoteOff_) {
|
||||
byte3 = score->getByteThree();
|
||||
instrument->noteOff(byte3*NORM_7);
|
||||
}
|
||||
else if (type == __SK_ControlChange_) {
|
||||
j = (int) score->getByteTwo();
|
||||
byte3 = score->getByteThree();
|
||||
instrument->controlChange(j,byte3);
|
||||
}
|
||||
else if (type == __SK_AfterTouch_) {
|
||||
j = (int) score->getByteTwo();
|
||||
instrument->controlChange(128,j);
|
||||
}
|
||||
else if (type == __SK_PitchBend_) {
|
||||
temp = score->getByteTwo();
|
||||
j = (int) temp;
|
||||
temp -= j;
|
||||
lastPitch = __MIDI_To_Pitch[j] * pow(2.0,temp / 12.0) ;
|
||||
instrument->setFreq(1, lastPitch); /* change osc1 pitch for now */
|
||||
}
|
||||
else if (type == __SK_ProgramChange_) {
|
||||
}
|
||||
}
|
||||
if (rtInput) {
|
||||
outOne += 1;
|
||||
if (outOne == MAX_IN_STRINGS) outOne = 0;
|
||||
}
|
||||
numStrings--;
|
||||
}
|
||||
}
|
||||
for (i=0;i<settleTime*SRATE;i++) { /* let the sound settle a little */
|
||||
output->tick(instrument->tick());
|
||||
}
|
||||
|
||||
delete output;
|
||||
delete score;
|
||||
delete instrument;
|
||||
|
||||
#if defined(__SGI_REALTIME_)
|
||||
if (rtInput) kill(string_thread, SIGKILL);
|
||||
#endif
|
||||
printf("MUS151 finished.\n");
|
||||
}
|
||||
177
mus151/MUS151.dsp
Normal file
177
mus151/MUS151.dsp
Normal file
@@ -0,0 +1,177 @@
|
||||
# Microsoft Developer Studio Project File - Name="MUS151" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 5.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=MUS151 - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MUS151.MAK".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MUS151.MAK" CFG="MUS151 - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "MUS151 - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "MUS151 - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "MUS151 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "MUS151__"
|
||||
# PROP BASE Intermediate_Dir "MUS151__"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# 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 BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "MUS151 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir ""
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# 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 BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib dsound.lib Wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "MUS151 - Win32 Release"
|
||||
# Name "MUS151 - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Envelope.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Envelope.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MUS151.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Object.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Object.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RawLoop.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RawLoop.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RawWave.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RawWave.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RTSoundIO.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RTSoundIO.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RTWvOut.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
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\SKINI11.msg
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\SKINI11.tbl
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\swapstuf.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\swapstuf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TwoOsc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\TwoOsc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\WvOut.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\WvOut.h
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
mus151/MUS151.dsw
Normal file
29
mus151/MUS151.dsw
Normal file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 5.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "MUS151"=.\MUS151.DSP - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
BIN
mus151/MUS151.ncb
Normal file
BIN
mus151/MUS151.ncb
Normal file
Binary file not shown.
65
mus151/Makefile
Normal file
65
mus151/Makefile
Normal file
@@ -0,0 +1,65 @@
|
||||
# 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.
|
||||
#
|
||||
# by Gary P. Scavone
|
||||
# CCRMA, Stanford University, 1998.
|
||||
|
||||
OS = $(shell uname)
|
||||
|
||||
# You will have to modify this path to correspond to the correct
|
||||
# location in your system. The following definition corresponds
|
||||
# to an STK project directory that is a subdirectory of the core
|
||||
# STK distribution.
|
||||
STK_PATH = ../
|
||||
|
||||
O_FILES = Object.o Envelope.o RawWave.o RawLoop.o \
|
||||
SKINI11.o swapstuf.o WvOut.o \
|
||||
RTWvOut.o RTSoundIO.o \
|
||||
\
|
||||
TwoOsc.o
|
||||
|
||||
RM = /bin/rm
|
||||
|
||||
ifeq ($(OS),IRIX) # These are for SGI
|
||||
INSTR = MUS151
|
||||
CC = CC -O # -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
|
||||
LIBRARY = -lpthread -lm
|
||||
# LIBRARY = /lib/libpthread.so.0 -lm
|
||||
endif
|
||||
|
||||
%.o : $(STK_PATH)%.cpp
|
||||
$(CC) -c $(<) -o $@
|
||||
|
||||
MUS151: MUS151.cpp $(O_FILES)
|
||||
$(CC) -o MUS151 MUS151.cpp $(O_FILES) $(LIBRARY)
|
||||
|
||||
# Personal $(O_FILES) :
|
||||
|
||||
TwoOsc.o : TwoOsc.cpp
|
||||
$(CC) -c TwoOsc.cpp
|
||||
|
||||
all: $(INSTR)
|
||||
|
||||
clean :
|
||||
rm *.o
|
||||
rm $(INSTR)
|
||||
|
||||
cleanIns :
|
||||
rm $(INSTR)
|
||||
|
||||
strip :
|
||||
strip $(INSTR)
|
||||
|
||||
|
||||
16
mus151/README-mus151.txt
Normal file
16
mus151/README-mus151.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
MUS151: An example project using STK
|
||||
|
||||
By Gary P. Scavone
|
||||
CCRMA, Stanford University, 1998.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Finally, it is simple to create a VC++ project directory that is completely separate from the STK core distribution. However, it appears that there is no simple way to redefine the location of the project files should you choose to relocate the project after it is created. You will probably have to manually "Add" all the core STK files to the VC++ project after moving the project directory.
|
||||
0
mus151/Release/.placeholder
Normal file
0
mus151/Release/.placeholder
Normal file
76
mus151/TwoOsc.cpp
Normal file
76
mus151/TwoOsc.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/********************************************/
|
||||
/* Two oscillator instrument for use */
|
||||
/* with MUS151 Psychoacoustics course. */
|
||||
/* by Gary P. Scavone & Oded Ben-Tal, 1998 */
|
||||
/* CCRMA, Stanford Unviversity */
|
||||
/********************************************/
|
||||
|
||||
#include "TwoOsc.h"
|
||||
|
||||
TwoOsc :: TwoOsc()
|
||||
{
|
||||
int i;
|
||||
|
||||
envelope = new Envelope; /* Envelope to avoid clicks */
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
osc[i] = new RawLoop("../rawwaves/sinewave.raw");
|
||||
osc[i]->normalize();
|
||||
osc[i]->setFreq((MY_FLOAT) 200.0);
|
||||
amps[i] = 0.2;
|
||||
}
|
||||
lastOutput = 0;
|
||||
}
|
||||
|
||||
TwoOsc :: ~TwoOsc()
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<2; i++) delete osc[i];
|
||||
delete envelope;
|
||||
}
|
||||
|
||||
void TwoOsc :: setFreq(int oscnum, MY_FLOAT frequency)
|
||||
{
|
||||
if (oscnum == 1) osc[0]->setFreq(frequency);
|
||||
else if (oscnum == 2) osc[1]->setFreq(frequency);
|
||||
}
|
||||
|
||||
void TwoOsc :: setAmp(int oscnum, MY_FLOAT amp)
|
||||
{
|
||||
if (oscnum == 1) amps[0] = amp;
|
||||
else if (oscnum == 2) amps[1] = amp;
|
||||
}
|
||||
|
||||
void TwoOsc :: noteOn(MY_FLOAT freq, MY_FLOAT amp)
|
||||
{
|
||||
envelope->keyOn();
|
||||
}
|
||||
|
||||
void TwoOsc :: noteOff(MY_FLOAT amp)
|
||||
{
|
||||
envelope->keyOff();
|
||||
}
|
||||
|
||||
MY_FLOAT TwoOsc :: tick()
|
||||
{
|
||||
lastOutput = 0.5 * envelope->tick() * (amps[0]*osc[0]->tick() + amps[1]*osc[1]->tick());
|
||||
return lastOutput;
|
||||
}
|
||||
|
||||
void TwoOsc :: controlChange(int number, MY_FLOAT value)
|
||||
{
|
||||
switch (number) {
|
||||
case 20:
|
||||
osc[0]->setFreq(value);
|
||||
break;
|
||||
case 21:
|
||||
osc[1]->setFreq(value);
|
||||
break;
|
||||
case 22:
|
||||
amps[0] = value * NORM_7;
|
||||
break;
|
||||
case 23:
|
||||
amps[1] = value * NORM_7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
35
mus151/TwoOsc.h
Normal file
35
mus151/TwoOsc.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/******************************************/
|
||||
/* Two oscillator instrument for use */
|
||||
/* with MUS151 Psychoacoustics course. */
|
||||
/* by Gary P. Scavone, 1998 */
|
||||
/* CCRMA, Stanford Unviversity */
|
||||
/******************************************/
|
||||
|
||||
#if !defined(__TwoOsc_h)
|
||||
#define __TwoOsc_h
|
||||
|
||||
//#include "../Instrmnt.h"
|
||||
#include "../Envelope.h"
|
||||
#include "../RawLoop.h"
|
||||
|
||||
|
||||
class TwoOsc : public Object
|
||||
{
|
||||
protected:
|
||||
Envelope *envelope;
|
||||
RawLoop *osc[2];
|
||||
MY_FLOAT lastOutput;
|
||||
MY_FLOAT amps[2];
|
||||
|
||||
public:
|
||||
TwoOsc();
|
||||
~TwoOsc();
|
||||
virtual void setFreq(int oscnum, MY_FLOAT frequency);
|
||||
virtual void setAmp(int oscnum, MY_FLOAT amp);
|
||||
virtual void noteOn(MY_FLOAT freq, MY_FLOAT amp);
|
||||
virtual void noteOff(MY_FLOAT amp);
|
||||
virtual MY_FLOAT tick();
|
||||
virtual void controlChange(int number, MY_FLOAT value);
|
||||
};
|
||||
|
||||
#endif
|
||||
201
mus151/tcl/TwoWaves.tcl
Normal file
201
mus151/tcl/TwoWaves.tcl
Normal file
@@ -0,0 +1,201 @@
|
||||
set pitch 64.0
|
||||
set osc1on 1
|
||||
set osc2on 1
|
||||
set freq1 200.0
|
||||
set freq2 200.0
|
||||
set amp1 20
|
||||
set amp2 20
|
||||
set outID "stdout"
|
||||
set commtype "stdout"
|
||||
|
||||
# Configure main window
|
||||
wm title . "MUS152 Two Oscillator Controller"
|
||||
wm iconname . "TwoOsc"
|
||||
. config -bg black
|
||||
|
||||
# Configure "communications" menu
|
||||
menu .menu -tearoff 0
|
||||
menu .menu.communication -tearoff 0
|
||||
.menu add cascade -label "Communication" -menu .menu.communication \
|
||||
-underline 0
|
||||
.menu.communication add radio -label "Console" -variable commtype \
|
||||
-value "stdout" -command { setComm }
|
||||
.menu.communication add radio -label "Socket" -variable commtype \
|
||||
-value "socket" -command { setComm }
|
||||
. configure -menu .menu
|
||||
|
||||
# Configure title display
|
||||
label .title -text "MUS151 Two Oscillator Controller" \
|
||||
-font {Times 14 bold} -background white \
|
||||
-foreground darkred -relief raised
|
||||
|
||||
label .title2 -text "by Gary P. Scavone\n Center for Computer Research in Music & Acoustics (CCRMA) \n Stanford University" \
|
||||
-font {Times 12 bold} -background white \
|
||||
-foreground darkred -relief raised
|
||||
|
||||
pack .title -padx 5 -pady 10
|
||||
pack .title2 -padx 5 -pady 10
|
||||
|
||||
# Configure "note-on" buttons
|
||||
frame .noteOn -bg black
|
||||
|
||||
button .noteOn.on -text NoteOn -bg grey66 -command { noteOn $pitch 64.0 }
|
||||
button .noteOn.off -text NoteOff -bg grey66 -command { noteOff $pitch 127.0 }
|
||||
button .noteOn.exit -text "Exit Program" -bg grey66 -command myExit
|
||||
pack .noteOn.on -side left -padx 5
|
||||
pack .noteOn.off -side left -padx 5 -pady 10
|
||||
pack .noteOn.exit -side left -padx 5 -pady 10
|
||||
|
||||
pack .noteOn
|
||||
|
||||
# Configure sliders
|
||||
frame .left -bg black
|
||||
|
||||
scale .left.freq1 -from 0 -to 10000 -length 400 \
|
||||
-command {changeParam 20 } \
|
||||
-orient horizontal -label "Frequency 1" \
|
||||
-tickinterval 2000 -showvalue true -bg grey66 \
|
||||
-variable freq1
|
||||
|
||||
scale .left.amp1 -from 0 -to 127 -length 400 \
|
||||
-command {changeParam 22 } \
|
||||
-orient horizontal -label "Amp 1" \
|
||||
-tickinterval 32 -showvalue true -bg grey66 \
|
||||
-variable amp1
|
||||
|
||||
scale .left.freq2 -from 0 -to 10000 -length 400 \
|
||||
-command {changeParam 21 } \
|
||||
-orient horizontal -label "Frequency 2" \
|
||||
-tickinterval 2000 -showvalue true -bg grey66 \
|
||||
-variable freq2
|
||||
|
||||
scale .left.amp2 -from 0 -to 127 -length 400 \
|
||||
-command {changeParam 23 } \
|
||||
-orient horizontal -label "Amp 2" \
|
||||
-tickinterval 32 -showvalue true -bg grey66 \
|
||||
-variable amp2
|
||||
|
||||
pack .left.freq1 -padx 10 -pady 3
|
||||
pack .left.amp1 -padx 10 -pady 3
|
||||
pack .left.freq2 -padx 10 -pady 3
|
||||
pack .left.amp2 -padx 10 -pady 3
|
||||
|
||||
pack .left -side left
|
||||
|
||||
# Configure more buttons
|
||||
frame .onOff -bg black
|
||||
|
||||
checkbutton .onOff.1 -text "Play Osc 1" -variable osc1on -relief flat \
|
||||
-command {setPlayStatus 22 $osc1on}
|
||||
checkbutton .onOff.2 -text "Play Osc 2" -variable osc2on -relief flat \
|
||||
-command {setPlayStatus 23 $osc2on}
|
||||
|
||||
pack .onOff.1 .onOff.2 -padx 5
|
||||
pack .onOff -side right -padx 5 -pady 10
|
||||
|
||||
proc myExit {} {
|
||||
global outID
|
||||
puts $outID [format "NoteOff 0.0 1 64 127" ]
|
||||
flush $outID
|
||||
puts $outID [format "ExitProgram"]
|
||||
flush $outID
|
||||
close $outID
|
||||
exit
|
||||
}
|
||||
|
||||
proc noteOn {pitchVal pressVal} {
|
||||
global outID
|
||||
puts $outID [format "NoteOn 0.0 1 %f %f" $pitchVal $pressVal]
|
||||
flush $outID
|
||||
}
|
||||
|
||||
proc noteOff {pitchVal pressVal} {
|
||||
global outID
|
||||
puts $outID [format "NoteOff 0.0 1 %f %f" $pitchVal $pressVal]
|
||||
flush $outID
|
||||
}
|
||||
|
||||
proc changeParam {controlNum value } {
|
||||
global outID freq1 freq2 amp1 amp2 osc1on osc2on
|
||||
if {$controlNum==20 || $controlNum==22} {
|
||||
if {$osc1on==1} {
|
||||
puts $outID [format "ControlChange 0.0 1 %d %f" $controlNum $value ]
|
||||
}
|
||||
} elseif {$controlNum==21 || $controlNum==23} {
|
||||
if {$osc2on==1} {
|
||||
puts $outID [format "ControlChange 0.0 1 %d %f" $controlNum $value ]
|
||||
}
|
||||
}
|
||||
flush $outID
|
||||
}
|
||||
|
||||
proc setPlayStatus {controlNum value } {
|
||||
global outID amp1 amp2 freq1 freq2
|
||||
if {$value==1} {
|
||||
if {$controlNum==22} {
|
||||
puts $outID [format "ControlChange 0.0 1 %d %f" 20 $freq1 ]
|
||||
puts $outID [format "ControlChange 0.0 1 %d %f" $controlNum $amp1 ]
|
||||
} elseif {$controlNum==23} {
|
||||
puts $outID [format "ControlChange 0.0 1 %d %f" 21 $freq2 ]
|
||||
puts $outID [format "ControlChange 0.0 1 %d %f" $controlNum $amp2 ]
|
||||
}
|
||||
} elseif {$value==0} {
|
||||
puts $outID [format "ControlChange 0.0 1 %d %f" $controlNum 0.0 ]
|
||||
}
|
||||
flush $outID
|
||||
}
|
||||
|
||||
# Socket connection procedure
|
||||
set d .socketdialog
|
||||
|
||||
proc setComm {} {
|
||||
global outID commtype 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]
|
||||
switch $i {
|
||||
0 {set commtype "socket"}
|
||||
1 {close $outID
|
||||
set outID "stdout"}
|
||||
}
|
||||
}
|
||||
} elseif { ![string compare "stdout" $outID] } {
|
||||
set sockport 2001
|
||||
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." \
|
||||
-background white -font {Helvetica 10 bold} \
|
||||
-wraplength 3i -justify left
|
||||
frame $d.sockport
|
||||
entry $d.sockport.entry -width 6
|
||||
label $d.sockport.text -text "Socket Port Number:" \
|
||||
-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
|
||||
$d.sockport.entry insert 0 $sockport
|
||||
frame $d.buttons
|
||||
button $d.buttons.cancel -text "Cancel" -bg grey66 \
|
||||
-command { set commtype "stdout"
|
||||
set outID "stdout"
|
||||
destroy $d }
|
||||
button $d.buttons.connect -text "Connect" -bg grey66 \
|
||||
-command {
|
||||
set sockport [$d.sockport.entry get]
|
||||
set err [catch {socket localhost $sockport} outID]
|
||||
if {$err == 0} {
|
||||
destroy $d
|
||||
} else {
|
||||
tk_dialog $d.error "Socket Error" {Error: Unable to make socket connection. Make sure the STK socket server is first running and that the port number is correct.} "" 0 OK
|
||||
} }
|
||||
pack $d.buttons.cancel -side left -padx 5 -pady 10
|
||||
pack $d.buttons.connect -side right -padx 5 -pady 10
|
||||
pack $d.buttons -side bottom -padx 5 -pady 10
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user