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