victor@2: /* victor@2: * main.cpp victor@2: * victor@2: * Created on: Oct 24, 2014 victor@2: * Author: Andrew McPherson and Victor Zappi victor@2: */ victor@2: victor@2: #include victor@2: #include victor@2: #include victor@2: #include victor@2: #include andrewm@5: #include victor@2: #include // to load audio files andrewm@56: giuliomoro@301: #include victor@2: #include "SampleData.h" victor@2: victor@2: using namespace std; victor@2: victor@2: // Load samples from file victor@2: int initFile(string file, SampleData *smp)//float *& smp) victor@2: { victor@2: SNDFILE *sndfile ; victor@2: SF_INFO sfinfo ; victor@2: victor@2: if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) { victor@2: cout << "Couldn't open file " << file << endl; victor@2: return 1; victor@2: } victor@2: victor@2: int numChan = sfinfo.channels; victor@2: if(numChan != 1) victor@2: { victor@2: cout << "Error: " << file << " is not a mono file" << endl; victor@2: return 1; victor@2: } victor@2: victor@2: smp->sampleLen = sfinfo.frames * numChan; victor@2: smp->samples = new float[smp->sampleLen]; victor@2: if(smp == NULL){ victor@2: cout << "Could not allocate buffer" << endl; victor@2: return 1; victor@2: } victor@2: victor@2: int subformat = sfinfo.format & SF_FORMAT_SUBMASK; victor@2: int readcount = sf_read_float(sndfile, smp->samples, smp->sampleLen); victor@2: victor@2: // Pad with zeros in case we couldn't read whole file victor@2: for(int k = readcount; k sampleLen; k++) victor@2: smp->samples[k] = 0; victor@2: victor@2: if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) { victor@2: double scale ; victor@2: int m ; victor@2: victor@2: sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ; victor@2: if (scale < 1e-10) victor@2: scale = 1.0 ; victor@2: else victor@2: scale = 32700.0 / scale ; victor@2: cout << "File samples scale = " << scale << endl; victor@2: victor@2: for (m = 0; m < smp->sampleLen; m++) victor@2: smp->samples[m] *= scale; victor@2: } victor@2: victor@2: sf_close(sndfile); victor@2: victor@2: return 0; victor@2: } victor@2: victor@2: victor@2: // Handle Ctrl-C by requesting that the audio rendering stop victor@2: void interrupt_handler(int var) victor@2: { victor@2: //rt_task_delete ((RT_TASK *) &gTriggerSamplesTask); victor@2: gShouldStop = true; victor@2: } victor@2: victor@2: // Print usage information victor@2: void usage(const char * processName) victor@2: { andrewm@5: cerr << "Usage: " << processName << " [options]" << endl; andrewm@5: giuliomoro@301: Bela_usage(); andrewm@5: andrewm@5: cerr << " --file [-f] filename: Name of the file to load (default is \"longsample.wav\")\n"; andrewm@5: cerr << " --help [-h]: Print this menu\n"; victor@2: } victor@2: victor@2: int main(int argc, char *argv[]) victor@2: { giuliomoro@301: BelaInitSettings settings; // Standard audio settings victor@2: string fileName; // Name of the sample to load victor@2: victor@2: SampleData sampleData; // User define structure to pass data retrieved from file to render function victor@2: sampleData.samples = 0; victor@2: sampleData.sampleLen = -1; victor@2: andrewm@5: andrewm@5: struct option customOptions[] = andrewm@5: { andrewm@5: {"help", 0, NULL, 'h'}, andrewm@5: {"file", 1, NULL, 'f'}, andrewm@5: {NULL, 0, NULL, 0} andrewm@5: }; andrewm@5: andrewm@5: // Set default settings giuliomoro@301: Bela_defaultSettings(&settings); andrewm@5: victor@2: // Parse command-line arguments victor@2: while (1) { victor@2: int c; giuliomoro@301: if ((c = Bela_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) victor@2: break; victor@2: switch (c) { victor@2: case 'h': victor@2: usage(basename(argv[0])); victor@2: exit(0); victor@2: case 'f': victor@2: fileName = string((char *)optarg); victor@2: break; victor@2: case '?': victor@2: default: victor@2: usage(basename(argv[0])); victor@2: exit(1); victor@2: } victor@2: } victor@2: victor@2: if(fileName.empty()){ victor@9: fileName = "filter/longsample.wav"; victor@2: } victor@2: andrewm@5: if(settings.verbose) { victor@2: cout << "Loading file " << fileName << endl; victor@2: } victor@2: victor@2: // Load file victor@2: if(initFile(fileName, &sampleData) != 0) victor@2: { victor@2: cout << "Error: unable to load samples " << endl; victor@2: return -1; victor@2: } victor@2: andrewm@5: if(settings.verbose) victor@2: cout << "File contains " << sampleData.sampleLen << " samples" << endl; victor@2: andrewm@5: victor@2: // Initialise the PRU audio device giuliomoro@301: if(Bela_initAudio(&settings, &sampleData) != 0) { victor@2: cout << "Error: unable to initialise audio" << endl; victor@2: return -1; victor@2: } victor@2: victor@2: // Start the audio device running giuliomoro@301: if(Bela_startAudio()) { victor@2: cout << "Error: unable to start real-time audio" << endl; victor@2: return -1; victor@2: } victor@2: andrewm@15: // Set up interrupt handler to catch Control-C and SIGTERM victor@2: signal(SIGINT, interrupt_handler); andrewm@15: signal(SIGTERM, interrupt_handler); victor@2: victor@2: // Run until told to stop victor@2: while(!gShouldStop) { victor@2: usleep(100000); victor@2: } victor@2: victor@2: // Stop the audio device giuliomoro@301: Bela_stopAudio(); victor@2: victor@2: // Clean up any resources allocated for audio giuliomoro@301: Bela_cleanupAudio(); victor@2: victor@2: // All done! victor@2: return 0; victor@2: } andrewm@5: