added wave writer code

master
Rachel Fae Fox (foxiepaws) 2020-03-09 23:35:58 -04:00
parent 52f3b75dc0
commit 7908c76d60
3 changed files with 183 additions and 0 deletions

View File

@ -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 <cstdarg>
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(){}

63
src/WavWriter/WavWriter.h Normal file
View File

@ -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 <cstdint>
#include <cstdio>
// 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: */

51
src/wavtest.cpp Normal file
View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#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<double,double> st = (*f)();
w->write(toint16(st.first/4.0), toint16(st.second/4.0));
}
w->finalise();
return 0;
}