diff --git a/src/WavWriter/WavWriter.cpp b/src/WavWriter/WavWriter.cpp new file mode 100644 index 0000000..3a06c9f --- /dev/null +++ b/src/WavWriter/WavWriter.cpp @@ -0,0 +1,69 @@ +/* + * Filename: WavWriter.cpp + * + * Description: + * + * + * Version: + * Created: Mon Mar 9 19:31:28 2020 + * Revision: None + * Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws + * + */ +#include "WavWriter.h" +#include + +WavWriter::WavWriter(char* filename, uint srate, uint chan, uint bps) { + file = fopen(filename, "w"); + sr = srate; + ch = chan; + bd = bps; + length = 0; + byterate = sr * ch * (bd/8); + blockalign = ch * (bd/8); + + // initialise the first 40 bytes for the header later. + for (int x = 0; x < 40; x++) { + fputc(0x00,file); + } +} +void WavWriter::writeHeader() { + rewind(file); + fprintf(file,"RIFF"); + writeBytes((char*) &riffsize,4); + fprintf(file,"WAVEfmt "); + writeBytes((char*) &fmtsize,4); + writeBytes((char*) &type,2); + writeBytes((char*) &ch,2); + writeBytes((char*) &sr,4); + writeBytes((char*) &byterate,4); + writeBytes((char*) &blockalign,2); + writeBytes((char*) &bd, 2); + fprintf(file,"data"); + writeBytes((char*) &datasize, 4); +} +void WavWriter::finalise() { + datasize = length; + riffsize = 20 + fmtsize + datasize; + writeHeader(); + fclose(file); +} + +void WavWriter::write(...) { + va_list args; + va_start(args, ch); + for (int i=0;i < ch;i++) { + uint32_t v = va_arg(args,int); + writeBytes((char*) &v,(bd/8)); + } + va_end(args); +} + +void WavWriter::writeBytes(char* bytes, uint count) { + for (int i = 0; i < count ; i++) { + length++; + putc(bytes[i],file); + } +} + +WavWriter::~WavWriter(){} diff --git a/src/WavWriter/WavWriter.h b/src/WavWriter/WavWriter.h new file mode 100644 index 0000000..97c6f4d --- /dev/null +++ b/src/WavWriter/WavWriter.h @@ -0,0 +1,63 @@ +/* + * Filename: WavWriter.h + * + * Description: + * + * + * Version: + * Created: Mon Mar 9 18:00:11 2020 + * Revision: None + * Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws + * + */ +#include +#include + +// standard wave files have a 32bit size limit. +#define WAVMAX (0xffffff - 20) + +typedef unsigned int uint; +class WavWriter { + + uint32_t length = 0; + uint32_t sr; // sample rate (gstool(samplerate)) + uint16_t bd; // bit depth (gstool(bitdepth)) + uint16_t ch; // channels (gstool(channels)) + uint32_t datasize; + uint32_t fmtsize = 16; + uint16_t type = 1; + uint32_t riffsize; + uint32_t byterate; + uint16_t blockalign; + FILE* file; + + // helpers + bool fit() { return (WAVMAX-fmtsize) > (length + byterate); } // see if one more sample will fit + void writeBytes(char* bytes, uint count); + + public: + // gstool + /* BEGIN GSTOOL GENERATED BLOCK */ + // getters + uint32_t samplerate() { return sr; } + uint16_t bitdepth() { return bd; } + uint16_t channels() { return ch; } + // setters + void samplerate(uint32_t v) { sr = v; } + void bitdepth(uint16_t v) { bd = v; } + void channels(uint16_t v) { ch = v; } + /* END GSTOOL GENERATED BLOCK */ + + WavWriter() {} + ~WavWriter(); + WavWriter(char* filename, uint srate, uint chan, uint bps); + void finalise(); + void writeHeader(); + void write(...); +}; + + +/* Local Variables: */ +/* mode: c++ */ +/* flycheck-clang-language-standard: "c++11" */ +/* End: */ diff --git a/src/wavtest.cpp b/src/wavtest.cpp new file mode 100644 index 0000000..ad7cb68 --- /dev/null +++ b/src/wavtest.cpp @@ -0,0 +1,51 @@ +/* + * Filename: wavtest.cpp + * + * Description: + * + * + * Version: + * Created: Mon Mar 9 23:06:08 2020 + * Revision: None + * Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws + * + */ + + +#include +#include +#include +#include "FM/Engine.h" +#include "WavWriter/WavWriter.h" + +int16_t toint16(double i) { + double temp = i *= 32767; + return floor(temp); +} +int main(int argc, char** argv){ + FM::Engine<2> *f = new FM::Engine<2>(); + f->getOperator(0)->setAll(2.0,0.0,0.0); + f->getOperator(0)->getEnvelope()->setAttackTime(1.0); + f->getOperator(0)->getEnvelope()->setDecayTime(0.5); + f->getOperator(0)->getEnvelope()->setMaxLevel(1.0); + f->getOperator(0)->getEnvelope()->setModMode(true); // play until reset. + f->getOperator(1)->getEnvelope()->setReleaseTime(2.5); + f->getOperator(1)->setAll(1.0,0.0,0.0); + f->setGainMatrix(0,0,0.0); // op1 fbl = 0 + f->setGainMatrix(0,1,1.0); // op1 -> op2 = 1 + f->setGainMatrix(1,0,0.0); // op2 -> op1 = 0 + f->setGainMatrix(1,2,1.0); // op2 -> out = 1 + f->freq = 440; + f->gate = true; + double seconds = 20; + // init a new writer + WavWriter *w = new WavWriter("wavtest.wav",44100,2,16); + for (int s = 0; s < 44100*seconds; s++) { + std::pair st = (*f)(); + w->write(toint16(st.first/4.0), toint16(st.second/4.0)); + } + w->finalise(); + return 0; +} + +