annotate projects/filter_IIR/main.cpp @ 45:579c86316008 newapi

Major API overhaul. Moved to a single data structure for handling render functions. Functionally, generally similar except for scheduling within PRU loop function, which now uses interrupts from the PRU rather than polling. This requires an updated kernel.
author andrewm
date Thu, 28 May 2015 14:35:55 -0400
parents 901d205d1a3c
children a6d223473ea2
rev   line source
victor@3 1 /*
victor@3 2 * main.cpp
victor@3 3 *
victor@3 4 * Created on: Oct 24, 2014
victor@3 5 * Author: Andrew McPherson and Victor Zappi
victor@3 6 */
victor@3 7
victor@3 8 #include <iostream>
victor@3 9 #include <cstdlib>
victor@3 10 #include <libgen.h>
victor@3 11 #include <signal.h>
victor@3 12 #include <string>
andrewm@5 13 #include <getopt.h>
victor@3 14 #include <sndfile.h> // to load audio files
victor@3 15 #include "../../include/RTAudio.h"
victor@3 16 #include "SampleData.h"
victor@3 17
victor@3 18 using namespace std;
victor@3 19
victor@3 20 float gCutFreq = 100;
victor@3 21
victor@3 22 // Load samples from file
victor@3 23 int initFile(string file, SampleData *smp)//float *& smp)
victor@3 24 {
victor@3 25 SNDFILE *sndfile ;
victor@3 26 SF_INFO sfinfo ;
victor@3 27
victor@3 28 if (!(sndfile = sf_open (file.c_str(), SFM_READ, &sfinfo))) {
victor@3 29 cout << "Couldn't open file " << file << endl;
victor@3 30 return 1;
victor@3 31 }
victor@3 32
victor@3 33 int numChan = sfinfo.channels;
victor@3 34 if(numChan != 1)
victor@3 35 {
victor@3 36 cout << "Error: " << file << " is not a mono file" << endl;
victor@3 37 return 1;
victor@3 38 }
victor@3 39
victor@3 40 smp->sampleLen = sfinfo.frames * numChan;
victor@3 41 smp->samples = new float[smp->sampleLen];
victor@3 42 if(smp == NULL){
victor@3 43 cout << "Could not allocate buffer" << endl;
victor@3 44 return 1;
victor@3 45 }
victor@3 46
victor@3 47 int subformat = sfinfo.format & SF_FORMAT_SUBMASK;
victor@3 48 int readcount = sf_read_float(sndfile, smp->samples, smp->sampleLen);
victor@3 49
victor@3 50 // Pad with zeros in case we couldn't read whole file
victor@3 51 for(int k = readcount; k <smp->sampleLen; k++)
victor@3 52 smp->samples[k] = 0;
victor@3 53
victor@3 54 if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE) {
victor@3 55 double scale ;
victor@3 56 int m ;
victor@3 57
victor@3 58 sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
victor@3 59 if (scale < 1e-10)
victor@3 60 scale = 1.0 ;
victor@3 61 else
victor@3 62 scale = 32700.0 / scale ;
victor@3 63 cout << "File samples scale = " << scale << endl;
victor@3 64
victor@3 65 for (m = 0; m < smp->sampleLen; m++)
victor@3 66 smp->samples[m] *= scale;
victor@3 67 }
victor@3 68
victor@3 69 sf_close(sndfile);
victor@3 70
victor@3 71 return 0;
victor@3 72 }
victor@3 73
victor@3 74 // Handle Ctrl-C by requesting that the audio rendering stop
victor@3 75 void interrupt_handler(int var)
victor@3 76 {
victor@3 77 //rt_task_delete ((RT_TASK *) &gTriggerSamplesTask);
victor@3 78 gShouldStop = true;
victor@3 79 }
victor@3 80
victor@3 81 // Print usage information
victor@3 82 void usage(const char * processName)
victor@3 83 {
andrewm@5 84 cerr << "Usage: " << processName << " [options]" << endl;
andrewm@5 85
andrewm@5 86 BeagleRT_usage();
andrewm@5 87
andrewm@5 88 cerr << " --file [-f] filename: Name of the file to load (default is \"longsample.wav\")\n";
andrewm@5 89 cerr << " --cutfreq [-c] freq: Set the cut off frequency of the filter in Hz\n";
andrewm@5 90 cerr << " --help [-h]: Print this menu\n";
victor@3 91 }
victor@3 92
victor@3 93 int main(int argc, char *argv[])
victor@3 94 {
andrewm@5 95 RTAudioSettings settings; // Standard audio settings
victor@3 96 string fileName; // Name of the sample to load
victor@3 97
victor@3 98 SampleData sampleData; // User define structure to pass data retrieved from file to render function
victor@3 99 sampleData.samples = 0;
victor@3 100 sampleData.sampleLen = -1;
victor@3 101
andrewm@5 102
andrewm@5 103 struct option customOptions[] =
andrewm@5 104 {
andrewm@5 105 {"help", 0, NULL, 'h'},
andrewm@5 106 {"cutfreq", 1, NULL, 'c'},
andrewm@5 107 {"file", 1, NULL, 'f'},
andrewm@5 108 {NULL, 0, NULL, 0}
andrewm@5 109 };
andrewm@5 110
andrewm@5 111 // Set default settings
andrewm@5 112 BeagleRT_defaultSettings(&settings);
andrewm@5 113
victor@3 114 // Parse command-line arguments
victor@3 115 while (1) {
victor@3 116 int c;
andrewm@5 117 if ((c = BeagleRT_getopt_long(argc, argv, "hf:c:", customOptions, &settings)) < 0)
victor@3 118 break;
victor@3 119 switch (c) {
victor@3 120 case 'h':
victor@3 121 usage(basename(argv[0]));
victor@3 122 exit(0);
victor@3 123 case 'f':
victor@3 124 fileName = string((char *)optarg);
victor@3 125 break;
victor@3 126 case 'c':
victor@3 127 gCutFreq = atof(optarg);
victor@3 128 break;
victor@3 129 case '?':
victor@3 130 default:
victor@3 131 usage(basename(argv[0]));
victor@3 132 exit(1);
victor@3 133 }
victor@3 134 }
victor@3 135
victor@3 136 if(fileName.empty()){
victor@9 137 fileName = "filter/longsample.wav";
victor@3 138 }
victor@3 139
andrewm@5 140 if(settings.verbose) {
victor@3 141 cout << "Loading file " << fileName << endl;
victor@3 142 }
victor@3 143
victor@3 144 // Load file
victor@3 145 if(initFile(fileName, &sampleData) != 0)
victor@3 146 {
victor@3 147 cout << "Error: unable to load samples " << endl;
victor@3 148 return -1;
victor@3 149 }
victor@3 150
andrewm@5 151 if(settings.verbose)
victor@3 152 cout << "File contains " << sampleData.sampleLen << " samples" << endl;
victor@3 153
andrewm@5 154
victor@3 155 // Initialise the PRU audio device
andrewm@5 156 if(BeagleRT_initAudio(&settings, &sampleData) != 0) {
victor@3 157 cout << "Error: unable to initialise audio" << endl;
victor@3 158 return -1;
victor@3 159 }
victor@3 160
victor@3 161 // Start the audio device running
andrewm@5 162 if(BeagleRT_startAudio()) {
victor@3 163 cout << "Error: unable to start real-time audio" << endl;
victor@3 164 return -1;
victor@3 165 }
victor@3 166
andrewm@15 167 // Set up interrupt handler to catch Control-C and SIGTERM
victor@3 168 signal(SIGINT, interrupt_handler);
andrewm@15 169 signal(SIGTERM, interrupt_handler);
victor@3 170
victor@3 171 // Run until told to stop
victor@3 172 while(!gShouldStop) {
victor@3 173 usleep(100000);
victor@3 174 }
victor@3 175
victor@3 176 // Stop the audio device
andrewm@5 177 BeagleRT_stopAudio();
victor@3 178
victor@3 179 // Clean up any resources allocated for audio
andrewm@5 180 BeagleRT_cleanupAudio();
victor@3 181
victor@3 182 // All done!
victor@3 183 return 0;
victor@3 184 }
andrewm@5 185