giuliomoro@250: /* giuliomoro@250: * main.cpp giuliomoro@250: * giuliomoro@250: * Created on: Oct 24, 2014 giuliomoro@250: * Author: parallels giuliomoro@250: */ giuliomoro@250: giuliomoro@250: #include giuliomoro@250: #include giuliomoro@250: #include giuliomoro@250: #include giuliomoro@250: #include giuliomoro@250: #include giuliomoro@250: #include giuliomoro@250: #include giuliomoro@250: #include // to load audio files giuliomoro@250: #include "SampleData.h" giuliomoro@250: #include giuliomoro@250: giuliomoro@250: using namespace std; giuliomoro@250: giuliomoro@250: // Global variables used by getCurrentTime() giuliomoro@250: unsigned long long gFirstSeconds, gFirstMicroseconds; giuliomoro@250: giuliomoro@250: // Load samples from file giuliomoro@250: int initFile(string file, SampleData *smp)//float *& smp) giuliomoro@250: { giuliomoro@250: SNDFILE *sndfile ; giuliomoro@250: SF_INFO sfinfo ; giuliomoro@250: giuliomoro@250: if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) { giuliomoro@250: cout << "Couldn't open file " << file << endl; giuliomoro@250: return 1; giuliomoro@250: } giuliomoro@250: giuliomoro@250: int numChan = sfinfo.channels; giuliomoro@250: if(numChan != 1) giuliomoro@250: { giuliomoro@250: cout << "Error: " << file << " is not a mono file" << endl; giuliomoro@250: return 1; giuliomoro@250: } giuliomoro@250: giuliomoro@250: smp->sampleLen = sfinfo.frames * numChan; giuliomoro@250: smp->samples = new float[smp->sampleLen]; giuliomoro@250: if(smp == NULL){ giuliomoro@250: cout << "Could not allocate buffer" << endl; giuliomoro@250: return 1; giuliomoro@250: } giuliomoro@250: giuliomoro@250: int subformat = sfinfo.format & SF_FORMAT_SUBMASK; giuliomoro@250: int readcount = sf_read_float(sndfile, smp->samples, smp->sampleLen); giuliomoro@250: giuliomoro@250: // Pad with zeros in case we couldn't read whole file giuliomoro@250: for(int k = readcount; k sampleLen; k++) giuliomoro@250: smp->samples[k] = 0; giuliomoro@250: giuliomoro@250: if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) { giuliomoro@250: double scale ; giuliomoro@250: int m ; giuliomoro@250: giuliomoro@250: sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ; giuliomoro@250: if (scale < 1e-10) giuliomoro@250: scale = 1.0 ; giuliomoro@250: else giuliomoro@250: scale = 32700.0 / scale ; giuliomoro@250: cout << "File samples scale = " << scale << endl; giuliomoro@250: giuliomoro@250: for (m = 0; m < smp->sampleLen; m++) giuliomoro@250: smp->samples[m] *= scale; giuliomoro@250: } giuliomoro@250: giuliomoro@250: sf_close(sndfile); giuliomoro@250: giuliomoro@250: return 0; giuliomoro@250: } giuliomoro@250: giuliomoro@250: giuliomoro@250: // Handle Ctrl-C by requesting that the audio rendering stop giuliomoro@250: void interrupt_handler(int var) giuliomoro@250: { giuliomoro@250: gShouldStop = true; giuliomoro@250: } giuliomoro@250: giuliomoro@250: // Print usage information giuliomoro@250: void usage(const char * processName) giuliomoro@250: { giuliomoro@250: cerr << "Usage: " << processName << " [options]" << endl; giuliomoro@250: giuliomoro@250: BeagleRT_usage(); giuliomoro@250: giuliomoro@250: cerr << " --help [-h]: Print this menu\n"; giuliomoro@250: } giuliomoro@250: giuliomoro@250: /* Function which returns the time since start of the program giuliomoro@250: * in (fractional) seconds. giuliomoro@250: */ giuliomoro@250: double getCurrentTime(void) { giuliomoro@250: unsigned long long result; giuliomoro@250: struct timeval tv; giuliomoro@250: giuliomoro@250: gettimeofday(&tv, NULL); giuliomoro@250: result = (tv.tv_sec - gFirstSeconds) * 1000000ULL + (tv.tv_usec - gFirstMicroseconds); giuliomoro@250: return (double)result / 1000000.0; giuliomoro@250: } giuliomoro@250: extern SampleData gSampleData; giuliomoro@250: int main(int argc, char *argv[]) giuliomoro@250: { giuliomoro@250: BeagleRTInitSettings settings; // Standard audio settings giuliomoro@250: struct timeval tv; giuliomoro@250: string fileName; // Name of the sample to load giuliomoro@250: giuliomoro@250: struct option customOptions[] = giuliomoro@250: { giuliomoro@250: {"help", 0, NULL, 'h'}, giuliomoro@250: {"file", 1, NULL, 'f'}, giuliomoro@250: {NULL, 0, NULL, 0} giuliomoro@250: }; giuliomoro@250: giuliomoro@250: gSampleData.samples = 0; giuliomoro@250: gSampleData.sampleLen = -1; giuliomoro@250: giuliomoro@250: // Set default settings giuliomoro@250: BeagleRT_defaultSettings(&settings); giuliomoro@250: giuliomoro@250: settings.periodSize = 32; // Larger period size by default, for testing giuliomoro@250: giuliomoro@250: // Parse command-line arguments giuliomoro@250: while (1) { giuliomoro@250: int c; giuliomoro@250: if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) giuliomoro@250: break; giuliomoro@250: switch (c) { giuliomoro@250: case 'h': giuliomoro@250: usage(basename(argv[0])); giuliomoro@250: exit(0); giuliomoro@250: case 'f': giuliomoro@250: fileName = string((char *)optarg); giuliomoro@250: break; giuliomoro@250: case '?': giuliomoro@250: default: giuliomoro@250: usage(basename(argv[0])); giuliomoro@250: exit(1); giuliomoro@250: } giuliomoro@250: } giuliomoro@250: giuliomoro@250: if(fileName.empty()){ giuliomoro@250: fileName = "sample.wav"; giuliomoro@250: } giuliomoro@250: giuliomoro@250: giuliomoro@250: // Load file giuliomoro@250: if(initFile(fileName, &gSampleData) != 0) giuliomoro@250: { giuliomoro@250: cout << "Error: unable to load samples " << endl; giuliomoro@250: return -1; giuliomoro@250: } giuliomoro@250: giuliomoro@250: if(settings.verbose) giuliomoro@250: cout << "File contains " << gSampleData.sampleLen << " samples" << endl; giuliomoro@250: giuliomoro@250: giuliomoro@250: // Initialise the PRU audio device giuliomoro@250: if(BeagleRT_initAudio(&settings, &gSampleData) != 0) { giuliomoro@250: cout << "Error: unable to initialise audio" << endl; giuliomoro@250: return -1; giuliomoro@250: } giuliomoro@250: giuliomoro@250: // Initialise time giuliomoro@250: gettimeofday(&tv, NULL); giuliomoro@250: gFirstSeconds = tv.tv_sec; giuliomoro@250: gFirstMicroseconds = tv.tv_usec; giuliomoro@250: giuliomoro@250: // Start the audio device running giuliomoro@250: if(BeagleRT_startAudio()) { giuliomoro@250: cout << "Error: unable to start real-time audio" << endl; giuliomoro@250: return -1; giuliomoro@250: } giuliomoro@250: giuliomoro@250: // Set up interrupt handler to catch Control-C giuliomoro@250: signal(SIGINT, interrupt_handler); giuliomoro@250: signal(SIGTERM, interrupt_handler); giuliomoro@250: giuliomoro@250: // Run until told to stop giuliomoro@250: while(!gShouldStop) { giuliomoro@250: usleep(100000); giuliomoro@250: } giuliomoro@250: giuliomoro@250: // Stop the audio device giuliomoro@250: BeagleRT_stopAudio(); giuliomoro@250: giuliomoro@250: // Clean up any resources allocated for audio giuliomoro@250: BeagleRT_cleanupAudio(); giuliomoro@250: giuliomoro@250: // All done! giuliomoro@250: return 0; giuliomoro@250: }