+++ /dev/null
-// WavFile.h
-//
-
-
-#ifndef WAVFILE_H
-#define WAVFILE_H
-
-#include <stdexcept>
-#include <string>
-#include <cstdlib>
-#include <cstdio>
-#include <cassert>
-#include <cstring>
-#include <limits.h>
-
-#ifndef uint
- typedef unsigned int uint;
-#endif
-
-const static char riffStr[] = "RIFF";
-const static char waveStr[] = "WAVE";
-const static char fmtStr[] = "fmt ";
-const static char dataStr[] = "data";
-
-typedef struct {
- char riff_char[4];
- int package_len;
- char wave[4];
-} WavRiff;
-
-typedef struct {
- char fmt[4];
- int format_len;
- short fixed;
- short channel_number;
- int sample_rate;
- int byte_rate;
- short byte_per_sample;
- short bits_per_sample;
-} WavFormat;
-
-typedef struct {
- char data_field[4];
- uint data_len;
-} WavData;
-
-
-typedef struct {
- WavRiff riff;
- WavFormat format;
- WavData data;
-} WavHeader;
-
-
-#ifdef BYTE_ORDER
- #if BYTE_ORDER == BIG_ENDIAN
- #define _BIG_ENDIAN_
- #endif
-#endif
-
-#ifdef _BIG_ENDIAN_
- static inline void _swap32 (unsigned int &dwData) {
- dwData = ((dwData >> 24) & 0x000000FF) |
- ((dwData >> 8) & 0x0000FF00) |
- ((dwData << 8) & 0x00FF0000) |
- ((dwData << 24) & 0xFF000000);
- }
-
- static inline void _swap16 (unsigned short &wData) {
- wData = ((wData >> 8) & 0x00FF) |
- ((wData << 8) & 0xFF00);
- }
-
- static inline void _swap16Buffer (unsigned short *pData, unsigned int dwNumWords) {
- unsigned long i;
-
- for (i = 0; i < dwNumWords; i ++) {
- _swap16 (pData[i]);
- }
- }
-
-#else // BIG_ENDIAN
- static inline void _swap32 (unsigned int &dwData) {
- // do nothing
- }
-
- static inline void _swap16 (unsigned short &wData) {
- // do nothing
- }
-
-
- static inline void _swap16Buffer (unsigned short *pData, unsigned int dwNumBytes) {
- // do nothing
- }
-
-#endif // BIG_ENDIAN
-
-// test if character code is between a white space ' ' and little 'z'
-static int isAlpha (char c) {
- return (c >= ' ' && c <= 'z') ? 1 : 0;
-}
-
-
-// test if all characters are between a white space ' ' and little 'z'
-static int isAlphaStr (char *str) {
- int c;
-
- c = str[0];
- while (c) {
- if (isAlpha(c) == 0) return 0;
- str ++;
- c = str[0];
- }
-
- return 1;
-}
-
-class WavInFile {
-public:
- WavInFile (const char *fileName) {
- int hdrsOk;
-
- // Try to open the file for reading
- fptr = fopen(fileName, "rb");
- if (fptr == NULL) {
- // didn't succeed
- std::string msg = "unable to open file \"";
- msg += fileName;
- msg += "\" for reading.";
- throw std::runtime_error(msg);
- }
-
- // Read the file headers
- hdrsOk = readWavHeaders();
- if (hdrsOk != 0) {
- // Something didn't match in the wav file headers
- std::string msg = "File \"";
- msg += fileName;
- msg += "\" is corrupt or not a WAV file";
- throw std::runtime_error(msg);
- }
-
- if (header.format.fixed != 1) {
- std::string msg = "File \"";
- msg += fileName;
- msg += "\" uses unsupported encoding.";
- throw std::runtime_error(msg);
- }
-
- dataRead = 0;
- }
-
-
-
- ~WavInFile() {
- close();
- }
-
-
-
- void rewind() {
- int hdrsOk;
-
- fseek(fptr, 0, SEEK_SET);
- hdrsOk = readWavHeaders();
- assert(hdrsOk == 0);
- dataRead = 0;
- }
-
-
- int checkCharTags() {
- // header.format.fmt should equal to 'fmt '
- if (memcmp(fmtStr, header.format.fmt, 4) != 0) return -1;
- // header.data.data_field should equal to 'data'
- if (memcmp(dataStr, header.data.data_field, 4) != 0) return -1;
-
- return 0;
- }
-
-
- int read(char *buffer, int maxElems) {
- int numBytes;
- uint afterDataRead;
-
- // ensure it's 8 bit format
- if (header.format.bits_per_sample != 8) {
- throw std::runtime_error("read(char*, int) works only with 8bit samples.");
- }
- assert(sizeof(char) == 1);
-
- numBytes = maxElems;
- afterDataRead = dataRead + numBytes;
- if (afterDataRead > header.data.data_len) {
- // Don't read more samples than are marked available in header
- numBytes = header.data.data_len - dataRead;
- assert(numBytes >= 0);
- }
-
- numBytes = fread(buffer, 1, numBytes, fptr);
- dataRead += numBytes;
-
- return numBytes;
- }
-
-
- int read(short *buffer, int maxElems) {
- unsigned int afterDataRead;
- int numBytes;
- int numElems;
-
- if (header.format.bits_per_sample == 8) {
- // 8 bit format
- char *temp = new char[maxElems];
- int i;
-
- numElems = read(temp, maxElems);
- // convert from 8 to 16 bit
- for (i = 0; i < numElems; i ++) {
- buffer[i] = temp[i] << 8;
- }
- delete[] temp;
- } else {
- // 16 bit format
- assert(header.format.bits_per_sample == 16);
- assert(sizeof(short) == 2);
-
- numBytes = maxElems * 2;
- afterDataRead = dataRead + numBytes;
- if (afterDataRead > header.data.data_len) {
- // Don't read more samples than are marked available in header
- numBytes = header.data.data_len - dataRead;
- assert(numBytes >= 0);
- }
-
- numBytes = fread(buffer, 1, numBytes, fptr);
- dataRead += numBytes;
- numElems = numBytes / 2;
-
- // 16bit samples, swap byte order if necessary
- _swap16Buffer((unsigned short *)buffer, numElems);
- }
-
- return numElems;
- }
-
-
-
- int read(float *buffer, int maxElems) {
- short *temp = new short[maxElems];
- int num;
- int i;
- double fscale;
-
- num = read(temp, maxElems);
-
- fscale = 1.0 / 32768.0;
- // convert to floats, scale to range [-1..+1[
- for (i = 0; i < num; i ++) {
- buffer[i] = (float)(fscale * (double)temp[i]);
- }
-
- delete[] temp;
-
- return num;
- }
-
- int read(double *buffer, int maxElems) {
- short *temp = new short[maxElems];
- int num;
- int i;
- double fscale;
-
- num = read(temp, maxElems);
-
- fscale = 1.0 / 32768.0;
- // convert to doubles, scale to range [-1..+1[
- for (i = 0; i < num; i ++) {
- buffer[i] = (double)(fscale * (double)temp[i]);
- }
-
- delete[] temp;
-
- return num;
- }
-
- int eof() const {
- // return true if all data has been read or file eof has reached
- return (dataRead == header.data.data_len || feof(fptr));
- }
-
-
- void close() {
- fclose(fptr);
- fptr = NULL;
- }
-
-
- int readRIFFBlock() {
- fread(&(header.riff), sizeof(WavRiff), 1, fptr);
-
- // swap 32bit data byte order if necessary
- _swap32((unsigned int &)header.riff.package_len);
-
- // header.riff.riff_char should equal to 'RIFF');
- if (memcmp(riffStr, header.riff.riff_char, 4) != 0) return -1;
- // header.riff.wave should equal to 'WAVE'
- if (memcmp(waveStr, header.riff.wave, 4) != 0) return -1;
-
- return 0;
- }
-
- int readHeaderBlock() {
- char label[5];
- std::string sLabel;
-
- // lead label std::string
- fread(label, 1, 4, fptr);
- label[4] = 0;
-
- if (isAlphaStr(label) == 0) return -1; // not a valid label
-
- // Decode blocks according to their label
- if (strcmp(label, fmtStr) == 0) {
- int nLen, nDump;
-
- // 'fmt ' block
- memcpy(header.format.fmt, fmtStr, 4);
-
- // read length of the format field
- fread(&nLen, sizeof(int), 1, fptr);
- // swap byte order if necessary
- _swap32((unsigned int &)nLen); // int format_len;
- header.format.format_len = nLen;
-
- // calculate how much length differs from expected
- nDump = nLen - (sizeof(header.format) - 8);
-
- // if format_len is larger than expected, read only as much data as we've space for
- if (nDump > 0) {
- nLen = sizeof(header.format) - 8;
- }
-
- // read data
- fread(&(header.format.fixed), nLen, 1, fptr);
-
- // swap byte order if necessary
- _swap16((unsigned short &)header.format.fixed); // short int fixed;
- _swap16((unsigned short &)header.format.channel_number); // short int channel_number;
- _swap32((unsigned int &)header.format.sample_rate); // int sample_rate;
- _swap32((unsigned int &)header.format.byte_rate); // int byte_rate;
- _swap16((unsigned short &)header.format.byte_per_sample); // short int byte_per_sample;
- _swap16((unsigned short &)header.format.bits_per_sample); // short int bits_per_sample;
-
- // if format_len is larger than expected, skip the extra data
- if (nDump > 0) {
- fseek(fptr, nDump, SEEK_CUR);
- }
-
- return 0;
- } else if (strcmp(label, dataStr) == 0) {
- // 'data' block
- memcpy(header.data.data_field, dataStr, 4);
- fread(&(header.data.data_len), sizeof(uint), 1, fptr);
-
- // swap byte order if necessary
- _swap32((unsigned int &)header.data.data_len);
-
- return 1;
- } else {
- uint len, i;
- uint temp;
- // unknown block
-
- // read length
- fread(&len, sizeof(len), 1, fptr);
- // scan through the block
- for (i = 0; i < len; i ++) {
- fread(&temp, 1, 1, fptr);
- if (feof(fptr)) return -1; // unexpected eof
- }
- }
- return 0;
- }
-
-
- int readWavHeaders() {
- int res;
-
- memset(&header, 0, sizeof(header));
-
- res = readRIFFBlock();
- if (res) return 1;
- // read header blocks until data block is found
- do {
- // read header blocks
- res = readHeaderBlock();
- if (res < 0) return 1; // error in file structure
- } while (res == 0);
- // check that all required tags are legal
- return checkCharTags();
- }
-
-
- uint getNumChannels() const {
- return header.format.channel_number;
- }
-
-
- uint getNumBits() const {
- return header.format.bits_per_sample;
- }
-
-
- uint getBytesPerSample() const {
- return getNumChannels() * getNumBits() / 8;
- }
-
-
- uint getSampleRate() const {
- return header.format.sample_rate;
- }
-
-
-
- uint getDataSizeInBytes() const {
- return header.data.data_len;
- }
-
-
- uint getNumSamples() const {
- return header.data.data_len / header.format.byte_per_sample;
- }
-
-
- uint getLengthMS() const {
- uint numSamples;
- uint sampleRate;
-
- numSamples = getNumSamples();
- sampleRate = getSampleRate();
-
- assert(numSamples < UINT_MAX / 1000);
- return (1000 * numSamples / sampleRate);
- }
-private:
- FILE *fptr;
- uint dataRead;
- WavHeader header;
-};
-
-
-/// Class for writing WAV audio files.
-class WavOutFile {
-private:
- /// Pointer to the WAV file
- FILE *fptr;
-
- /// WAV file header data.
- WavHeader header;
-
- /// Counter of how many bytes have been written to the file so far.
- int bytesWritten;
-
-public:
- //////////////////////////////////////////////////////////////////////////////
- //
- // Class WavOutFile
- //
-
- WavOutFile(const char *fileName, int sampleRate, int bits, int channels) {
- bytesWritten = 0;
- fptr = fopen(fileName, "wb");
- if (fptr == NULL) {
- std::string msg = "unable to open file \"";
- msg += fileName;
- msg += "\" for writing.";
- //pmsg = msg.c_str;
- throw std::runtime_error(msg);
- }
-
- fillInHeader(sampleRate, bits, channels);
- writeHeader();
- }
-
-
-
- ~WavOutFile() {
- close();
- }
-
-
-
- void fillInHeader(uint sampleRate, uint bits, uint channels) {
- // fill in the 'riff' part..
-
- // copy std::string 'RIFF' to riff_char
- memcpy(&(header.riff.riff_char), riffStr, 4);
- // package_len unknown so far
- header.riff.package_len = 0;
- // copy std::string 'WAVE' to wave
- memcpy(&(header.riff.wave), waveStr, 4);
-
-
- // fill in the 'format' part..
-
- // copy std::string 'fmt ' to fmt
- memcpy(&(header.format.fmt), fmtStr, 4);
-
- header.format.format_len = 0x10;
- header.format.fixed = 1;
- header.format.channel_number = (short)channels;
- header.format.sample_rate = sampleRate;
- header.format.bits_per_sample = (short)bits;
- header.format.byte_per_sample = (short)(bits * channels / 8);
- header.format.byte_rate = header.format.byte_per_sample * sampleRate;
- header.format.sample_rate = sampleRate;
-
- // fill in the 'data' part..
-
- // copy std::string 'data' to data_field
- memcpy(&(header.data.data_field), dataStr, 4);
- // data_len unknown so far
- header.data.data_len = 0;
- }
-
-
- void finishHeader() {
- // supplement the file length into the header structure
- header.riff.package_len = bytesWritten + 36;
- header.data.data_len = bytesWritten;
-
- writeHeader();
- }
-
-
-
- void writeHeader() {
- WavHeader hdrTemp;
-
- // swap byte order if necessary
- hdrTemp = header;
- _swap32((unsigned int &)hdrTemp.riff.package_len);
- _swap32((unsigned int &)hdrTemp.format.format_len);
- _swap16((unsigned short &)hdrTemp.format.fixed);
- _swap16((unsigned short &)hdrTemp.format.channel_number);
- _swap32((unsigned int &)hdrTemp.format.sample_rate);
- _swap32((unsigned int &)hdrTemp.format.byte_rate);
- _swap16((unsigned short &)hdrTemp.format.byte_per_sample);
- _swap16((unsigned short &)hdrTemp.format.bits_per_sample);
- _swap32((unsigned int &)hdrTemp.data.data_len);
-
- // write the supplemented header in the beginning of the file
- fseek(fptr, 0, SEEK_SET);
- fwrite(&hdrTemp, sizeof(hdrTemp), 1, fptr);
- // jump back to the end of the file
- fseek(fptr, 0, SEEK_END);
- }
-
-
-
- void close() {
- finishHeader();
- fclose(fptr);
- fptr = NULL;
- }
-
-
- void write(const char *buffer, int numElems) {
- int res;
-
- if (header.format.bits_per_sample != 8) {
- throw std::runtime_error("write(const char*, int) accepts only 8bit samples.");
- }
- assert(sizeof(char) == 1);
-
- res = fwrite(buffer, 1, numElems, fptr);
- if (res != numElems) {
- throw std::runtime_error("problem while writing to a wav file.");
- }
-
- bytesWritten += numElems;
- }
-
-
- void write(const short *buffer, int numElems) {
- int res;
-
- // 16 bit samples
- if (numElems < 1) return; // nothing to do
-
- if (header.format.bits_per_sample == 8) {
- int i;
- char *temp = new char[numElems];
- // convert from 16bit format to 8bit format
- for (i = 0; i < numElems; i ++) {
- temp[i] = buffer[i] >> 8;
- }
- // write in 8bit format
- write(temp, numElems);
- delete[] temp;
- } else {
- // 16bit format
- unsigned short *pTemp = new unsigned short[numElems];
-
- assert(header.format.bits_per_sample == 16);
-
- // allocate temp buffer to swap byte order if necessary
- memcpy(pTemp, buffer, numElems * 2);
- _swap16Buffer(pTemp, numElems);
-
- res = fwrite(pTemp, 2, numElems, fptr);
-
- delete[] pTemp;
-
- if (res != numElems) {
- throw std::runtime_error("problem while writing to a wav file.");
- }
- bytesWritten += 2 * numElems;
- }
- }
-
-
- void write(const float *buffer, int numElems) {
- int i;
- short *temp = new short[numElems];
- int iTemp;
-
- // convert to 16 bit integer
- for (i = 0; i < numElems; i ++) {
- // convert to integer
- iTemp = (int)(32768.0f * buffer[i]);
-
- // saturate
- if (iTemp < -32768) iTemp = -32768;
- if (iTemp > 32767) iTemp = 32767;
- temp[i] = (short)iTemp;
- }
-
- write(temp, numElems);
-
- delete[] temp;
- }
-
- void write(const double *buffer, int numElems) {
- int i;
- short *temp = new short[numElems];
- int iTemp;
-
- // convert to 16 bit integer
- for (i = 0; i < numElems; i ++) {
- // convert to integer
- iTemp = (int)(32768.0f * buffer[i]);
-
- // saturate
- if (iTemp < -32768) iTemp = -32768;
- if (iTemp > 32767) iTemp = 32767;
- temp[i] = (short)iTemp;
- }
-
- write(temp, numElems);
-
- delete[] temp;
- }
-
-};
-
-#endif
+++ /dev/null
-// analysis.h
-//
-
-#ifndef ANALYSIS_H
-#define ANALYSIS_H
-
-#include "WavFile.h"
-#include "utilities.h"
-#include "parser.h"
-#include "FFT.h"
-#include "features.h"
-
-#include <vector>
-#include <string>
-#include <stdexcept>
-#include <memory>
-
-struct Descriptors {
- std::vector<double> highest_peak_Hz;
- std::vector<double> irr;
- std::vector<double> energy; //implemented in features.h
- std::vector<double> zcr; //implemented in features.h
-};
-
-void analyse (const std::string& fname, Parameters& p, Descriptors& d) {
- WavInFile in (fname.c_str ());
- if (in.getSampleRate () != p.sr) {
- std::stringstream err;
- err << "invalid sampling rate in " << fname << ": " << in.getSampleRate () << " vs" << p.sr;
- throw std::runtime_error (err.str ());
- }
- int nsamps = in.getNumSamples ();
-
- std::vector<double> samples (nsamps);
- if (in.getNumChannels () == 1) {
- in.read (&samples[0], nsamps);
- } else if (in.getNumChannels () == 2) {
- std::vector<double> stereo_samples (nsamps * 2);
- in.read (&stereo_samples[0], nsamps);
- for (unsigned i = 0; i < nsamps; ++i) {
- samples[i] = .5 * stereo_samples[2 * i] + .5 * stereo_samples[2 * i +1];
- }
- } else {
- std::stringstream err;
- err << "invalid number of channels in << " << fname << "(mono or stereo only)";
- throw std::runtime_error (err.str ());
- }
-
- std::vector<double> buffer (p.fft_size * 2); // complex
- std::vector<double> window (p.fft_size);
- makeWindow<double> (&window[0], p.fft_size, .5, .5, 0); // hanning
- double winEnergy = 0;
- for (unsigned i = 0; i < p.fft_size; ++i) {
- winEnergy += window[i] * window[i];
- }
- std::vector<double> amps (p.fft_size / 2); // discard symmetry
- std::vector<double> freqs (p.fft_size / 2); // discard symmetry
- for (unsigned i = 0; i < p.fft_size / 2; ++i) {
- freqs[i] = p.sr / p.fft_size * i;
- }
- int ptr = 0;
- while (ptr < nsamps) {
- if (p.fft_size + ptr > nsamps) break; // discard incomplete frame
-
- memset (&buffer[0], 0, sizeof (double) * 2 * p.fft_size);
- for (unsigned i = 0; i < p.fft_size; ++i) {
- buffer[2 * i] = window[i] * samples[i + ptr];
- }
- fft (&buffer[0], p.fft_size, -1);
-
- // double max_peak = 0;
- // int max_pos = 0;
- // for (unsigned i = 0; i < p.fft_size; ++i) {
- // double r = buffer[2 * i];
- // double im = buffer[2 * i + 1];
- // double a = sqrt (r * r + im * im);
- // if (a > max_peak) {
- // max_peak = a;
- // max_pos = i;
- // }
- // }
- // d.highest_peak_Hz.push_back ((p.sr / p.fft_size) * max_pos);
-
- for (unsigned i = 0; i < p.fft_size / 2; ++i) {
- double r = buffer[2 * i];
- double im = buffer[2 * i + 1];
- double a = sqrt (r * r + im * im);
- amps[i] = a;
- }
- double c = speccentr (&s[0], &freqs[0], p.fft_size / 2);
- d.highest_peak_Hz.push_back (c);
-
- double irr = specirr (&s[0], p.fft_size / 2);
- d.irr.push_back (irr);
-
- double z = zcr<double> (&samples[ptr], p.fft_size);
- d.zcr.push_back (z);
-
- double sum = 0;
- for (int i = 0; i < p.fft_size; ++i) {
- double a = samples[i + ptr];
- sum += a * a;
- }
- d.energy.push_back (std::sqrt (sum / p.fft_size));
-
- ptr += p.hop_size;
- }
-}
-
-#endif // ANALYSIS_H
-
-// EOF
+++ /dev/null
-// basic file operations
-#include <iostream>
-#include <fstream>
-
-void writefile(const std::string path, const std::string filename) {
- std::ofstream myfile;
- myfile.open (path + filename);
- myfile << "Writing this to a file.\n";
- myfile.close();
-}
+++ /dev/null
-// parser.h
-//
-
-#ifndef PARSER_H
-#define PARSER_H
-
-struct Parameters {
- double sr;
- int fft_size;
- int hop_size;
- int width;
- int height;
- int zoom;
-};
-
-#endif // PARSER_H
-
-// EOF
+++ /dev/null
-// svg_utils.h
-
-#ifndef SVG_UTILS_H
-#define SVG_UTILS_H
-
-#include <vector>
-#include <string>
-#include <sstream>
-#include <fstream>
-
-#include <iostream>
-
- // Utility XML/String Functions.
- template <typename T>
- std::string attribute(std::string const & attribute_name,
- T const & value, std::string const & unit = "")
- {
- std::stringstream ss;
- ss << attribute_name << "=\"" << value << unit << "\" ";
- return ss.str();
- }
- std::string elemStart(std::string const & element_name)
- {
- return "\t<" + element_name + " ";
- }
- std::string elemEnd(std::string const & element_name)
- {
- return "</" + element_name + ">\n";
- }
- std::string emptyElemEnd()
- {
- return "/>\n";
- }
-
- // Quick optional return type. This allows functions to return an invalid
- // value if no good return is possible. The user checks for validity
- // before using the returned value.
- template <typename T>
- class optional
- {
- public:
- optional<T>(T const & type)
- : valid(true), type(type) { }
- optional<T>() : valid(false), type(T()) { }
- T * operator->()
- {
- // If we try to access an invalid value, an exception is thrown.
- if (!valid)
- throw std::exception();
-
- return &type;
- }
- // Test for validity.
- bool operator!() const { return !valid; }
- private:
- bool valid;
- T type;
- };
-
- struct Dimensions
- {
- Dimensions(double width, double height) : width(width), height(height) { }
- Dimensions(double combined = 0) : width(combined), height(combined) { }
- double width;
- double height;
- };
-
- struct pPoint
- {
- pPoint(double x = 0, double y = 0) : x(x), y(y) { }
- double x;
- double y;
- };
- optional<pPoint> getMinPoint(std::vector<pPoint> const & pPoints)
- {
- if (pPoints.empty())
- return optional<pPoint>();
-
- pPoint min = pPoints[0];
- for (unsigned i = 0; i < pPoints.size(); ++i) {
- if (pPoints[i].x < min.x)
- min.x = pPoints[i].x;
- if (pPoints[i].y < min.y)
- min.y = pPoints[i].y;
- }
- return optional<pPoint>(min);
- }
- optional<pPoint> getMaxPoint(std::vector<pPoint> const & pPoints)
- {
- if (pPoints.empty())
- return optional<pPoint>();
-
- pPoint max = pPoints[0];
- for (unsigned i = 0; i < pPoints.size(); ++i) {
- if (pPoints[i].x > max.x)
- max.x = pPoints[i].x;
- if (pPoints[i].y > max.y)
- max.y = pPoints[i].y;
- }
- return optional<pPoint>(max);
- }
-
- // Defines the dimensions, scale, origin, and origin offset of the document.
- struct Layout
- {
- enum Origin { TopLeft, BottomLeft, TopRight, BottomRight };
-
- Layout(Dimensions const & dimensions = Dimensions(400, 300), Origin origin = BottomLeft,
- double scale = 1, pPoint const & origin_offset = pPoint(0, 0))
- : dimensions(dimensions), scale(scale), origin(origin), origin_offset(origin_offset) { }
- Dimensions dimensions;
- double scale;
- Origin origin;
- pPoint origin_offset;
- };
-
- // Convert coordinates in user space to SVG native space.
- double translateX(double x, Layout const & layout)
- {
- if (layout.origin == Layout::BottomRight || layout.origin == Layout::TopRight)
- return layout.dimensions.width - ((x + layout.origin_offset.x) * layout.scale);
- else
- return (layout.origin_offset.x + x) * layout.scale;
- }
-
- double translateY(double y, Layout const & layout)
- {
- if (layout.origin == Layout::BottomLeft || layout.origin == Layout::BottomRight)
- return layout.dimensions.height - ((y + layout.origin_offset.y) * layout.scale);
- else
- return (layout.origin_offset.y + y) * layout.scale;
- }
- double translateScale(double dimension, Layout const & layout)
- {
- return dimension * layout.scale;
- }
-
- class Serializeable
- {
- public:
- Serializeable() { }
- virtual ~Serializeable() { };
- virtual std::string toString(Layout const & layout) const = 0;
- };
-
- class Color : public Serializeable
- {
- public:
- enum Defaults { Transparent = -1, Aqua, Black, Blue, Brown, Cyan, Fuchsia,
- Green, Lime, Magenta, Orange, Purple, Red, Silver, White, Yellow };
-
- Color(int r, int g, int b) : transparent(false), red(r), green(g), blue(b) { }
- Color(Defaults color)
- : transparent(false), red(0), green(0), blue(0)
- {
- switch (color)
- {
- case Aqua: assign(0, 255, 255); break;
- case Black: assign(0, 0, 0); break;
- case Blue: assign(0, 0, 255); break;
- case Brown: assign(165, 42, 42); break;
- case Cyan: assign(0, 255, 255); break;
- case Fuchsia: assign(255, 0, 255); break;
- case Green: assign(0, 128, 0); break;
- case Lime: assign(0, 255, 0); break;
- case Magenta: assign(255, 0, 255); break;
- case Orange: assign(255, 165, 0); break;
- case Purple: assign(128, 0, 128); break;
- case Red: assign(255, 0, 0); break;
- case Silver: assign(192, 192, 192); break;
- case White: assign(255, 255, 255); break;
- case Yellow: assign(255, 255, 0); break;
- default: transparent = true; break;
- }
- }
- virtual ~Color() { }
- std::string toString(Layout const &) const
- {
- std::stringstream ss;
- if (transparent)
- ss << "transparent";
- else
- ss << "rgb(" << red << "," << green << "," << blue << ")";
- return ss.str();
- }
- private:
- bool transparent;
- int red;
- int green;
- int blue;
-
- void assign(int r, int g, int b)
- {
- red = r;
- green = g;
- blue = b;
- }
- };
-
- class Fill : public Serializeable
- {
- public:
- Fill(Color::Defaults color) : color(color) { }
- Fill(Color color = Color::Transparent)
- : color(color) { }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << attribute("fill", color.toString(layout));
- return ss.str();
- }
- private:
- Color color;
- };
-
- class Stroke : public Serializeable
- {
- public:
- Stroke(double width = -1, Color color = Color::Transparent)
- : width(width), color(color) { }
- std::string toString(Layout const & layout) const
- {
- // If stroke width is invalid.
- if (width < 0)
- return std::string();
-
- std::stringstream ss;
- ss << attribute("stroke-width", translateScale(width, layout)) << attribute("stroke", color.toString(layout));
- return ss.str();
- }
- private:
- double width;
- Color color;
- };
-
- class Font : public Serializeable
- {
- public:
- Font(double size = 12, std::string const & family = "Verdana") : size(size), family(family) { }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << attribute("font-size", translateScale(size, layout)) << attribute("font-family", family);
- return ss.str();
- }
- private:
- double size;
- std::string family;
- };
-
- class Shape : public Serializeable
- {
- public:
- Shape(Fill const & fill = Fill(), Stroke const & stroke = Stroke())
- : fill(fill), stroke(stroke) { }
- virtual ~Shape() { }
- virtual std::string toString(Layout const & layout) const = 0;
- virtual void offset(pPoint const & offset) = 0;
- protected:
- Fill fill;
- Stroke stroke;
- };
- template <typename T>
- std::string vectorToString(std::vector<T> collection, Layout const & layout)
- {
- std::string combination_str;
- for (unsigned i = 0; i < collection.size(); ++i)
- combination_str += collection[i].toString(layout);
-
- return combination_str;
- }
-
- class Circle : public Shape
- {
- public:
- Circle(pPoint const & center, double diameter, Fill const & fill,
- Stroke const & stroke = Stroke())
- : Shape(fill, stroke), center(center), radius(diameter / 2) { }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << elemStart("circle") << attribute("cx", translateX(center.x, layout))
- << attribute("cy", translateY(center.y, layout))
- << attribute("r", translateScale(radius, layout)) << fill.toString(layout)
- << stroke.toString(layout) << emptyElemEnd();
- return ss.str();
- }
- void offset(pPoint const & offset)
- {
- center.x += offset.x;
- center.y += offset.y;
- }
- private:
- pPoint center;
- double radius;
- };
-
- class Elipse : public Shape
- {
- public:
- Elipse(pPoint const & center, double width, double height,
- Fill const & fill = Fill(), Stroke const & stroke = Stroke())
- : Shape(fill, stroke), center(center), radius_width(width / 2),
- radius_height(height / 2) { }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << elemStart("ellipse") << attribute("cx", translateX(center.x, layout))
- << attribute("cy", translateY(center.y, layout))
- << attribute("rx", translateScale(radius_width, layout))
- << attribute("ry", translateScale(radius_height, layout))
- << fill.toString(layout) << stroke.toString(layout) << emptyElemEnd();
- return ss.str();
- }
- void offset(pPoint const & offset)
- {
- center.x += offset.x;
- center.y += offset.y;
- }
- private:
- pPoint center;
- double radius_width;
- double radius_height;
- };
-
- class Rectangle : public Shape
- {
- public:
- Rectangle(pPoint const & edge, double width, double height,
- Fill const & fill = Fill(), Stroke const & stroke = Stroke())
- : Shape(fill, stroke), edge(edge), width(width),
- height(height) { }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << elemStart("rect") << attribute("x", translateX(edge.x, layout))
- << attribute("y", translateY(edge.y, layout))
- << attribute("width", translateScale(width, layout))
- << attribute("height", translateScale(height, layout))
- << fill.toString(layout) << stroke.toString(layout) << emptyElemEnd();
- return ss.str();
- }
- void offset(pPoint const & offset)
- {
- edge.x += offset.x;
- edge.y += offset.y;
- }
- private:
- pPoint edge;
- double width;
- double height;
- };
-
- class Line : public Shape
- {
- public:
- Line(pPoint const & start_pPoint, pPoint const & end_pPoint,
- Stroke const & stroke = Stroke())
- : Shape(Fill(), stroke), start_pPoint(start_pPoint),
- end_pPoint(end_pPoint) { }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << elemStart("line") << attribute("x1", translateX(start_pPoint.x, layout))
- << attribute("y1", translateY(start_pPoint.y, layout))
- << attribute("x2", translateX(end_pPoint.x, layout))
- << attribute("y2", translateY(end_pPoint.y, layout))
- << stroke.toString(layout) << emptyElemEnd();
- return ss.str();
- }
- void offset(pPoint const & offset)
- {
- start_pPoint.x += offset.x;
- start_pPoint.y += offset.y;
-
- end_pPoint.x += offset.x;
- end_pPoint.y += offset.y;
- }
- private:
- pPoint start_pPoint;
- pPoint end_pPoint;
- };
-
- class Polygon : public Shape
- {
- public:
- Polygon(Fill const & fill = Fill(), Stroke const & stroke = Stroke())
- : Shape(fill, stroke) { }
- Polygon(Stroke const & stroke = Stroke()) : Shape(Color::Transparent, stroke) { }
- Polygon & operator<<(pPoint const & pPoint)
- {
- pPoints.push_back(pPoint);
- return *this;
- }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << elemStart("polygon");
-
- ss << "points=\"";
- for (unsigned i = 0; i < pPoints.size(); ++i)
- ss << translateX(pPoints[i].x, layout) << "," << translateY(pPoints[i].y, layout) << " ";
- ss << "\" ";
-
- ss << fill.toString(layout) << stroke.toString(layout) << emptyElemEnd();
- return ss.str();
- }
- void offset(pPoint const & offset)
- {
- for (unsigned i = 0; i < pPoints.size(); ++i) {
- pPoints[i].x += offset.x;
- pPoints[i].y += offset.y;
- }
- }
- private:
- std::vector<pPoint> pPoints;
- };
-
- class Polyline : public Shape
- {
- public:
- Polyline(Fill const & fill = Fill(), Stroke const & stroke = Stroke())
- : Shape(fill, stroke) { }
- Polyline(Stroke const & stroke = Stroke()) : Shape(Color::Transparent, stroke) { }
- Polyline(std::vector<pPoint> const & pPoints,
- Fill const & fill = Fill(), Stroke const & stroke = Stroke())
- : Shape(fill, stroke), pPoints(pPoints) { }
- Polyline & operator<<(pPoint const & pPoint)
- {
- pPoints.push_back(pPoint);
- return *this;
- }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << elemStart("polyline");
-
- ss << "Points=\"";
- for (unsigned i = 0; i < pPoints.size(); ++i)
- ss << translateX(pPoints[i].x, layout) << "," << translateY(pPoints[i].y, layout) << " ";
- ss << "\" ";
-
- ss << fill.toString(layout) << stroke.toString(layout) << emptyElemEnd();
- return ss.str();
- }
- void offset(pPoint const & offset)
- {
- for (unsigned i = 0; i < pPoints.size(); ++i) {
- pPoints[i].x += offset.x;
- pPoints[i].y += offset.y;
- }
- }
- std::vector<pPoint> pPoints;
- };
-
- class Text : public Shape
- {
- public:
- Text(pPoint const & origin, std::string const & content, Fill const & fill = Fill(),
- Font const & font = Font(), Stroke const & stroke = Stroke())
- : Shape(fill, stroke), origin(origin), content(content), font(font) { }
- std::string toString(Layout const & layout) const
- {
- std::stringstream ss;
- ss << elemStart("text") << attribute("x", translateX(origin.x, layout))
- << attribute("y", translateY(origin.y, layout))
- << fill.toString(layout) << stroke.toString(layout) << font.toString(layout)
- << ">" << content << elemEnd("text");
- return ss.str();
- }
- void offset(pPoint const & offset)
- {
- origin.x += offset.x;
- origin.y += offset.y;
- }
- private:
- pPoint origin;
- std::string content;
- Font font;
- };
-
- // Sample charting class.
- class LineChart : public Shape
- {
- public:
- LineChart(Dimensions margin = Dimensions(), double scale = 1,
- Stroke const & axis_stroke = Stroke(.5, Color::Purple))
- : axis_stroke(axis_stroke), margin(margin), scale(scale) { }
- LineChart & operator<<(Polyline const & polyline)
- {
- if (polyline.pPoints.empty())
- return *this;
-
- polylines.push_back(polyline);
- return *this;
- }
- std::string toString(Layout const & layout) const
- {
- if (polylines.empty())
- return "";
-
- std::string ret;
- for (unsigned i = 0; i < polylines.size(); ++i)
- ret += polylineToString(polylines[i], layout);
-
- return ret + axisString(layout);
- }
- void offset(pPoint const & offset)
- {
- for (unsigned i = 0; i < polylines.size(); ++i)
- polylines[i].offset(offset);
- }
- private:
- Stroke axis_stroke;
- Dimensions margin;
- double scale;
- std::vector<Polyline> polylines;
-
- optional<Dimensions> getDimensions() const
- {
- if (polylines.empty())
- return optional<Dimensions>();
-
- optional<pPoint> min = getMinPoint(polylines[0].pPoints);
- optional<pPoint> max = getMaxPoint(polylines[0].pPoints);
- for (unsigned i = 0; i < polylines.size(); ++i) {
- if (getMinPoint(polylines[i].pPoints)->x < min->x)
- min->x = getMinPoint(polylines[i].pPoints)->x;
- if (getMinPoint(polylines[i].pPoints)->y < min->y)
- min->y = getMinPoint(polylines[i].pPoints)->y;
- if (getMaxPoint(polylines[i].pPoints)->x > max->x)
- max->x = getMaxPoint(polylines[i].pPoints)->x;
- if (getMaxPoint(polylines[i].pPoints)->y > max->y)
- max->y = getMaxPoint(polylines[i].pPoints)->y;
- }
-
- return optional<Dimensions>(Dimensions(max->x - min->x, max->y - min->y));
- }
- std::string axisString(Layout const & layout) const
- {
- optional<Dimensions> dimensions = getDimensions();
- if (!dimensions)
- return "";
-
- // Make the axis 10% wider and higher than the data Points.
- double width = dimensions->width * 1.1;
- double height = dimensions->height * 1.1;
-
- // Draw the axis.
- Polyline axis(Color::Transparent, axis_stroke);
- axis << pPoint(margin.width, margin.height + height) << pPoint(margin.width, margin.height)
- << pPoint(margin.width + width, margin.height);
-
- return axis.toString(layout);
- }
- std::string polylineToString(Polyline const & polyline, Layout const & layout) const
- {
- Polyline shifted_polyline = polyline;
- shifted_polyline.offset(pPoint(margin.width, margin.height));
-
- std::vector<Circle> vertices;
- for (unsigned i = 0; i < shifted_polyline.pPoints.size(); ++i)
- vertices.push_back(Circle(shifted_polyline.pPoints[i], getDimensions()->height / 30.0, Color::Black));
-
- return shifted_polyline.toString(layout) + vectorToString(vertices, layout);
- }
- };
-
- class Document
- {
- public:
- Document(std::string const & file_name, Layout layout = Layout())
- : file_name(file_name), layout(layout) { }
-
- Document & operator<<(Shape const & shape)
- {
- body_nodes_str += shape.toString(layout);
- return *this;
- }
- std::string toString() const
- {
- std::stringstream ss;
- ss << "<?xml " << attribute("version", "1.0") << attribute("standalone", "no")
- << "?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "
- << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg "
- << attribute("width", layout.dimensions.width, "px")
- << attribute("height", layout.dimensions.height, "px")
- << attribute("xmlns", "http://www.w3.org/2000/svg")
- << attribute("version", "1.1") << ">\n" << body_nodes_str << elemEnd("svg");
- return ss.str();
- }
- bool save() const
- {
- std::ofstream ofs(file_name.c_str());
- if (!ofs.good())
- return false;
-
- ofs << toString();
- ofs.close();
- return true;
- }
- private:
- std::string file_name;
- Layout layout;
-
- std::string body_nodes_str;
- };
-
-#endif // SVG_UTILS_H
-
-// EOF
-
+++ /dev/null
-// utilities.h
-//
-
-
-#ifndef UTILITIES_H
-#define UTILITIES_H
-
-#include <dirent.h>
-
-#include <fstream>
-#include <vector>
-#include <sstream>
-#include <string>
-#include <stdexcept>
-#include <iostream>
-#include <map>
-#include <deque>
-#include <cmath>
-
-// -----------------------------------------------------------------------------
-std::string removePath (const std::string& in) {
- size_t pos = std::string::npos;
- pos = in.find_last_of ("/");
- if (pos != std::string::npos) {
- return in.substr (pos + 1, in.size () - pos);
- } else return in;
-}
-
-std::string removeExtension (const std::string& in) {
- size_t pos = std::string::npos;
- pos = in.find_last_of (".");
- if (pos != std::string::npos) {
- return in.substr (0, pos);
- } else return in;
-}
-
-std::string trim (std::string const& source,
- char const* delims = " \t\r\n") {
- std::string result (source);
- std::string::size_type index = result.find_last_not_of (delims);
- if (index != std::string::npos)
- result.erase (++index);
-
- index = result.find_first_not_of (delims);
- if (index != std::string::npos)
- result.erase (0, index);
- else
- result.erase ();
- return result;
-}
-
-void erase_substring (std::string & mainStr, const std::string & toErase) {
- // Search for the substring in string
- size_t pos = mainStr.find(toErase);
-
- if (pos != std::string::npos) {
- // If found then erase it from string
- mainStr.erase(pos, toErase.length());
- }
-}
-
-
-
-std::vector<std::string> split_by_pipe (const std::string& input) {
- std::istringstream ss(input);
- std::string token;
-
- std::vector<std::string> res;
- while(std::getline(ss, token, '|')) {
- res.push_back(token);
- }
-
- return res;
-}
-
-// -----------------------------------------------------------------------------
-// search for regexp at beginning of text
-bool match_star (int c, char *regexp, char *text);
-bool match_here (char* regexp, char* text) {
- if (regexp[0] == '\0') return true;
- if (regexp[1] == '*') return match_star (regexp[0], regexp + 2, text);
- if (regexp[0] == '$' && regexp[1] == '\0') return *text == '\0';
- if (*text != '\0' && (regexp[0] == '.' || regexp[0] == *text)) {
- return match_here (regexp + 1, text + 1);
- }
- return false;
-}
-
-// leftmost longest search for c*regexp */
-bool match_star (int c, char *regexp, char *text) {
- char *t;
-
- for (t = text; *t != '\0' && (*t == c || c == '.'); t++)
- ;
- do { /* * matches zero or more */
- if (match_here(regexp, t)) return true;
- } while (t-- > text);
- return false;
-}
-
-// search for regexp anywhere in text
-bool match (char* regexp, char* text) {
- if (regexp[0] == '^')
- return match_here (regexp + 1, text);
- do {
- if (match_here (regexp, text)) return true;
- } while (*text++ != '\0');
- return false;
-}
-// -----------------------------------------------------------------------------
-template <typename T>
-void save_vector (const char* file, const std::vector<T>& v) {
- std::ofstream out (file);
- if (!out.good ()) {
- throw std::runtime_error ("cannot create output file");
- }
-
- for (unsigned i = 0; i < v.size (); ++i) {
- out << v[i] << " ";
- }
- out.close ();
-}
-
-// -----------------------------------------------------------------------------
-template <typename T>
-void interleave (T* stereo, const T* l, const T* r, int n) {
- for (int i = 0; i < n; ++i) {
- stereo[2 * i] = l[i];
- stereo[2 * i + 1] = r[i];
- }
-}
-
-template <typename T>
-void deinterleave (const T* stereo, T* l, T* r, int n) {
- for (int i = 0; i < n; ++i) {
- l[i] = stereo[2 * i];
- r[i] = stereo[2 * i + 1];
- }
-}
-
-// -----------------------------------------------------------------------------
-
-template <typename T>
-T cents_to_ratio (int cents) {
- T c = cents;
- c /= 1200.;
- return std::pow (2., c);
-}
-
-long pitch_buffer_to_midi (char *pitch_string) {
- int base = 0;
- char *cur = pitch_string;
- switch (*cur) {
- case 'c':
- case 'C':
- base = 0;
- break;
- case 'd':
- case 'D':
- base = 2;
- break;
- case 'e':
- case 'E':
- base = 4;
- break;
- case 'f':
- case 'F':
- base = 5;
- break;
- case 'g':
- case 'G':
- base = 7;
- break;
- case 'a':
- case 'A':
- base = 9;
- break;
- case 'b':
- case 'B':
- base = 11;
- break;
- default:
- // possibily throw error
- return 0;
- }
- cur++;
-
- bool alt = 0;
- if (*cur == '#') {
- alt = 1;
- cur++;
- }
-
- return (atoi(cur)+1)*12+base+alt;
-}
-
-long pitch_buffer_to_cents (char *pitch_string) {
- return pitch_buffer_to_midi(pitch_string)*100;
-}
-
-inline bool file_exists (const std::string& name) {
- std::ifstream f(name.c_str());
- return f.good();
-}
-
-// inframes contains INTERLEAVED samples for all channels
-template <typename T>
-long resample(T* inframes, long nsamps, std::vector<T>& outframes, double old_sr,
- double new_sr, double fmax, double window_width, long num_channels) {
- double factor = new_sr / old_sr;
- long num_in_frames = nsamps / num_channels;
- long num_out_frames = (long)ceil(num_in_frames * factor);
-
- // clear and initialize output vector
- outframes.clear();
- for (long i = 0; i < num_out_frames; i++)
- outframes.push_back(0.);
-
- for (long ch = 0; ch < num_channels; ch++) {
- for (long s = 0; s < num_out_frames; s++) {
- long i, j;
- double x = s / factor;
- double r_w, r_a, r_snc;
- double r_g = 2 * fmax / new_sr; // Calc gain correction factor
- double r_y = 0;
- for (i = -window_width/2; i < window_width/2; i++) { // For 1 window width
- j = (long)(x + i); // Calc input sample index
- //rem calculate von Hann Window. Scale and calculate Sinc
- r_w = 0.5 - 0.5 * cos (2. * M_PI * (0.5 + (j - x) / window_width));
- r_a = 2. * M_PI * (j - x)*fmax/new_sr;
- r_snc = (r_a != 0 ? r_snc = sin(r_a)/r_a : 1);
- if (j >= 0 && j < num_in_frames) {
- r_y = r_y + r_g * r_w * r_snc * inframes[num_channels * j + ch];
- }
- }
- outframes[num_channels * s + ch] = r_y; // Return new filtered sample
- }
- }
- return num_out_frames * num_channels;
-}
-
-#endif // UTILITIES_H
-
-// EOF