// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Tue May 2 05:04:58 PDT 2006 (copied from sndpower) // Last Modified: Tue May 2 20:11:48 PDT 2006 // Filename: ...soundfile/examples/smoothpower.cpp // Syntax: C++ // // Description: Calculate the average signal power for given durations // #include "soundfile.h" #include <stdlib.h> #include <math.h> #ifndef OLDCPP #include <iostream> #include <iomanip> using namespace std; #else #include <iostream.h> #include <iomanip.h> #endif void printLongSummary(SoundFileRead& soundfile, int totalframes, int start, int chunk); double filterk = 0.3; // set with -k option double smoothq = 1; // set with -S option int achannel = -1; // set with -c option int roundq = 1; // set with -R option int centerq = 1; const char *comment = ""; // set with --comment option const char *datestring = ""; // set with -d option int main(int argc, char** argv) { Options options; options.define("a|average=i:441", "Number of samples to average over"); options.define("s|start=i:0", "Starting sample"); options.define("c|channel=i:-1", "Channel to analyze"); options.define("C|no-center=b", "Do not center the timing data"); options.define("d|date=s:", "Date string"); options.define("comment=s:", "Comment string"); options.define("R|no-rounding=b", "Turn off db value rounding"); options.define("S|no-smoothing=b", "Turn off smoothing"); options.define("k|smoothing=d:0.3", "the 1/2 smoothing filter value"); options.define("n|count=i:-1", "Number of analyses to make"); options.define("all=b", "calculate the energy of the entire file"); options.define("q|quiet=b", "suppress printing of header info"); options.process(argc, argv); if (options.getArgCount() == 0) { cout << "Usage: " << options.getCommand() << " filename" << endl; exit(1); } SoundFileRead soundfile(options.getArg(1)); filterk = options.getDouble("smoothing"); smoothq = !options.getBoolean("no-smoothing"); achannel = options.getInteger("channel"); roundq = !options.getBoolean("no-rounding"); centerq = !options.getBoolean("no-center"); if (options.getBoolean("comment")) { comment = options.getString("comment"); } if (options.getBoolean("date")) { datestring = options.getString("date"); } int chunk = options.getInteger("average"); int start = options.getInteger("start"); int totalframes = options.getInteger("count"); if (totalframes <= 0) { totalframes = (soundfile.getSamples() - start)/chunk + 1; } // print header information if (!options.getBoolean("quiet")) { cout << "###Filename:\t\t" << options.getArg(1) << "\n"; cout << "###FrameSize:\t\t" << chunk << " samples; "; cout << 1000.0 * chunk/soundfile.getSrate() << " milliseconds" << "\n"; cout << "###FrameCount:\t\t" << totalframes << "\n"; if (datestring[0] != '\0') { cout << "###AnalysisDate:\t" << datestring << "\n"; } if (comment[0] != '\0') { cout << "###Comment:\t\t" << comment << "\n"; } cout << "###Smoothing:\t\t"; if (smoothq) { cout << filterk; } else { cout << 1; } cout << "\n"; cout << "###Channel:\t\t"; if (achannel < 0) { if (soundfile.getChannels() == 1) { cout << "all (mono)"; } else if (soundfile.getChannels() == 2) { cout << "all (stereo)"; } else if (soundfile.getChannels() == 4) { cout << "all (quad)"; } else { cout << "all"; } } else { cout << achannel; if (achannel == 0) { cout << " (left)"; } else if (achannel == 1) { cout << " (right)"; } } cout << "\n"; cout << "# time (seconds), dB\n"; } if (options.getBoolean("all")) { printLongSummary(soundfile, 1, 0, soundfile.getSamples()); } else { printLongSummary(soundfile, totalframes, start, chunk); } return 0; } ////////////////////////////// // // printLongSummary -- // void printLongSummary(SoundFileRead& soundfile, int totalframes, int start, int chunk) { double sum, value, db; int i, j, channel; Array<double> dbvalues; dbvalues.setSize(totalframes); dbvalues.allowGrowth(0); for (i=0; i<totalframes; i++) { sum = 0.0; for (j=0; j<chunk; j++) { if (achannel < 0) { for (channel=0; channel < soundfile.getChannels(); channel++) { value = soundfile.getCurrentSampleDouble(channel); sum += value * value; } } else { value = soundfile.getCurrentSampleDouble(achannel); sum += value * value; } soundfile.incrementSample(); } if (sum == 0.0) { db = -100; } else { db = 10.0 * log10(sum/chunk/soundfile.getChannels()); } if (!smoothq) { if (centerq) { cout << (double)((i+0.5) * chunk)/soundfile.getSrate(); } else { cout << (double)(i * chunk)/soundfile.getSrate(); } if (roundq) { cout << "\t" << ((int)(db * 10.0 + 0.5))/10.0 << "\n"; } else { cout << "\t" << db << "\n"; } } else { dbvalues[i] = db; } } if (!smoothq) { return; } // Difference equation for smoothing: y[n] = k * x[n] + (1-k) * y[n-1] // do first half of smoothing: double oneminusk = 1.0 - filterk; for (i=1; i<totalframes; i++) { dbvalues[i] = filterk * dbvalues[i] + oneminusk * dbvalues[i-1]; } // do second half of smoothing: for (i=totalframes-2; i>=0; i--) { dbvalues[i] = filterk * dbvalues[i] + oneminusk * dbvalues[i+1]; } // print results: for (i=0; i<totalframes; i++) { cout << (double)(i * chunk)/soundfile.getSrate(); if (roundq) { cout << "\t" << ((int)(dbvalues[i] * 10.0 + 0.5))/10.0 << "\n"; } else { cout << "\t" << dbvalues[i] << "\n"; } } } // md5sum: 9df46191f314438a1cc3887e5791c510 smoothpower.cpp [20060701]