annotate projects/samples/main.cpp @ 12:a6beeba3a648

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