#include #include "csound.h" /********************************************************************/ /* This program uses Csound as a realtime audio IO wrapper. */ /* Users can create their own processing algorithms by modifying */ /* the ProcessBlock() function below. The ProcessBlock() function */ /* was designed to resemble the processing functions found in most */ /* audio plugin sdks */ /* */ /* To build the program make sure you have the latest version of */ /* Csound installed. Then run the following command line. Remember */ /* to change the paths below to point to your own Csound lib and */ /* header file directories */ /* */ /* gcc realtimeIOCsound.c -o example1.exe /* -IC:/MyDocuments/SourceCode/Csound5/csoundInstall/Csound/include /* -LC:/MyDocuments/SourceCode/Csound5/csoundInstall/Csound/bin /* -lcsound32 /* */ /* If in MS windows your compiler can't find csound32 go to the */ /* Csound bin folder and copy and rename csound.5.2.dll to */ /* csound32.lib */ /* */ /* On OSX un the following command: /* Macintosh:Documents rorywalsh$ gcc RealtimeIOwrapper.c -o test /* -I/Library/Frameworks/CsoundLib.framework/Versions/Current/headers /* -framework CsoundLib /* */ /* To run the program simply run the binary from from the command line. /* You can overwrite the IO devices by passing -odevuadioN */ /* and -idevaudioN to the command line, where N is the device */ /* number. Pass -idevuadio99 to get a list of all the devices */ /* */ /* Hit 0 and Enter to quit the program at any time */ /* */ /* One final note, in order for the program to run properly */ /* you must have write access to the disk your running the */ /* program from. This is because the program writes a csd file */ /* to disk before calling csoundCompile() */ /* */ /* Rory Wlash 2010 */ /* */ /********************************************************************/ /*--------------------------------------------------*/ /* userData structure declaration */ /* member of this struct can be accessed from our */ /* ProcessBlock() function */ /*--------------------------------------------------*/ typedef struct { int result; //result of csoundCompile() CSOUND* csound; //instacne of Csound int PERF_STATUS; //tells us if Csound is running int cnt; //counter for our ProcessBlock() MYFLT delayline[88200]; //delay buffer, used in ProcessBlock() }userData; /*------------------------------------------------------*/ /* To prototype processing algorithms simply */ /* edit this function. 'input' will be a numSamples */ /* sized block of samples. Fill output with numSamples */ /* number of samples */ /*------------------------------------------------------*/ void ProcessBlock(void* data, MYFLT* input, MYFLT* output, int numSamples) { userData* udata = (userData*)data; //access our userData structure int index; //sample index MYFLT in,out; /* simple delay line */ for(index=0;indexdelayline[udata->cnt]; udata->delayline[udata->cnt] = in; udata->cnt++; if (udata->cnt >= 44100) udata->cnt = 0; output[index] = out+in; } } //processing thread uintptr_t csThread(void *clientData); //creates a simply Csound file that accessing realtime input using -idac int CreateInputFile(char* csdFileName); /*------------------------------------------------------*/ /* main function */ /*------------------------------------------------------*/ /* The only think you need to in here is initiliase */ /* members of our userData */ /* struct */ /*------------------------------------------------------*/ int main(int argc, char *argv[]) { /*----------------------------------------------*/ /* create userData structure and initialise */ /* it's members */ /*----------------------------------------------*/ userData* ud; ud = (userData *)malloc(sizeof(userData)); ud->csound=csoundCreate(NULL); ud->cnt=0; ud->result=0; ud->PERF_STATUS=1; //create temp Csound file CreateInputFile("temp.csd"); /* allocate enough memory for our Csound command line */ int noOfArgs=5; char** inputArgs = (char **) malloc(sizeof(char*)*(5)); inputArgs[0] = "csound"; inputArgs[1] = "temp.csd"; inputArgs[2] = "-odevaudio"; inputArgs[3] = "-idevaudio"; inputArgs[4] = "-g"; //override with command line args if they're present if(argc>1) inputArgs[2] = argv[1]; if(argc>2) inputArgs[3] = argv[2]; /* compile Csound */ csoundInitialize(&noOfArgs, &inputArgs, 0); ud->result=csoundCompile(ud->csound,noOfArgs,inputArgs); int userInput=200; void* ThreadID; if(!ud->result) { ud->PERF_STATUS=1; ThreadID = csoundCreateThread(csThread, (void*)ud); } else{ printf("csoundCompile returned an error"); return 0; } printf("\nPress 0 and then Enter to quit this program\n"); while(userInput!=0){ scanf("%d", &userInput); } ud->PERF_STATUS=0; csoundDestroy(ud->csound); free(ud); free(inputArgs); return 1; } //------------------------------------------------------------- //performance thread function def //------------------------------------------------------------- uintptr_t csThread(void *data) { userData* udata = (userData*)data; int ksmps = csoundGetKsmps(udata->csound); MYFLT* input; input = (MYFLT*)malloc(sizeof(MYFLT)*ksmps); MYFLT* output; output = (MYFLT*)malloc(sizeof(MYFLT)*ksmps); if(!udata->result) { while(csoundPerformKsmps(udata->csound) == 0 && udata->PERF_STATUS==1){ if(csoundChanOAGet(udata->csound, input, 1)!=0){ printf("error retrieving buffer from Csound"); udata->PERF_STATUS=0; } //call processing block ProcessBlock((void*)udata, input, output, ksmps); if(csoundChanIASet(udata->csound, output, 2)!=0){ printf("error sending buffer to Csound"); udata->PERF_STATUS=0; } } } csoundDestroy(udata->csound); udata->PERF_STATUS = 0; return 1; } //--------------------------------------------------------------- //write a simple audio IO-CSD file to disk for Csound to compile //--------------------------------------------------------------- int CreateInputFile(char* csdFileName){ int result=0; int i, octave, pitch, amplitude, startTime; startTime = 0; const char* fileContents; /* create a file pointer */ FILE *csdFile; /* open a file for writing */ csdFile=fopen(csdFileName, "w"); /* make sure the file opened properly */ if(csdFile == 0){ printf("Could not create Csound file.\n"); return 0; } else{ /* create a string that contains our Csound code but leave out the complete score, this will be written in the for loop that follows */ const char* fileContents= "\n" "\n" "-b128\n" "\n" "\n" "sr = 44100\n" "ksmps = 64\n" "nchnls = 1\n" "\n" "instr 1\n" "a1 inch 1\n" "chano a1, 1\n" "a2 chani 2\n" "out a2\n" "endin\n" "\n" " \n" "\n" "f1 0 1024 10 1\n" "i1 0 3600\n" "\n" ""; /* write this teh above to disk */ result = fprintf(csdFile, fileContents); if(result<0){ printf("Error writing data to file"); return 0; } fclose(csdFile); } return 1; }