123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- #include "synth.hpp"
- #include <math.h>
- #include <iostream>
- #include <stdlib.h> /* srand, rand */
- #include <sekai/mfcc.h>
- #include <json/json.h>
- #include <iostream>
- #include <fstream>
- #include <sekai/common.h>
- #define TWOPI (2*M_PI)
- using namespace std;
- extern std::string basedir;
- double midi_freq(float m) {
- /* converts a MIDI note number to a frequency
- <http://en.wikipedia.org/wiki/MIDI_Tuning_Standard> */
- return 440 * pow(2, (double)(m-69.0)/12.0);
- }
- Synth::Synth()
- {
- //FIXME
- }
- void Synth::init(int samplerate,int buffer_size)
- {
- this->samplerate = samplerate;
- this->buffer_size = buffer_size;
-
- enabled = false;
-
- reader = new VVDReader();
- int fft_size = 2048;
- fprintf(stderr,"sample_rate=%i\n",samplerate);
- synth = new WorldSynth2(1024*1024*1024,fft_size,samplerate);
-
- //jsoncpp is only used by this test program
- ifstream ifs(basedir+"/voice.json");
- Json::Reader jreader;
- Json::Value arr;
- jreader.parse(ifs, arr);
-
- for (int i = 0; i < arr.size(); i++){
- std::string vvd = arr[i]["vvd"].asString();
- auto x = arr[i]["x"];
- auto y = arr[i]["y"];
- bool valid = reader->addVVD(basedir+"/"+vvd);
- if(!valid) {
- fprintf(stderr,"invalid vvd\n");
- abort();
- }
- if(x.size()!=y.size())
- {
- fprintf(stderr,"invalid entry in voices.json\n");
- abort();
- }
- segment* seg = new segment;
- seg->count=x.size();
- seg->x=new float[seg->count];
- seg->y=new float[seg->count];
- for (int j = 0; j < x.size(); j++){
- seg->x[j]=x[j].asInt()*0.001;
- seg->y[j]=y[j].asInt()*0.001;
- }
- segments.push_back(seg);
- }
-
-
-
- vvddata = (float*) new char[reader->getFrameSize()];//FIXME add allocator for vvddata
-
- }
- Synth::~Synth()
- {
- }
- void Synth::noteOn(int notenum, int velocity)
- {
- this->notenum = notenum;
-
- int pitch = (int)(midi_freq(notenum)+0.5);
- printf("pitch %i notenum %i\n",pitch,notenum);
-
- int current_samples = synth->currentTime();//time in samples
- float current_time = current_samples*1.0/samplerate;
-
- switch(notenum % 12)
- {
- case 0:
- current_oto = 0;
- break;
- case 2:
- current_oto = 1;
- break;
- case 4:
- current_oto = 2;
- break;
- case 5:
- current_oto = 3;
- break;
- case 7:
- current_oto = 4;
- break;
- case 9:
- current_oto = 5;
- break;
- case 11:
- current_oto = 6;
- break;
- default:
- current_oto = 7;
- }
-
- //fprintf(stderr,"select %i\n",reader->selectVVD(current_oto));
-
-
- if(current_oto!=7)
- {
- segment* seg = segments[current_oto];
- float delta = current_time - seg->x[0];
- for(int i=0;i<seg->count;i++)
- {
- seg->x[i]+=delta;
- }
- reader->selectVVD(current_oto);
- enabled = true;
- }
- else
- enabled = false;
-
-
- }
- void Synth::noteOff(int notenum)
- {
- this->notenum = 0;
- enabled=false;
- #if 0
- if(notenum==this->notenum)
- {
- lastnote=this->notenum;
- this->notenum=0;
- current_frame=0;
- current_oto = 7;
- }
- fprintf(stderr,"select %i\n",vvdreader->selectVVD(current_oto));
- #endif
- }
- float Synth::getCurrentF0(int pos)
- {
- (void) pos;
- if(notenum) return (float)midi_freq(notenum);
- else return 0.0;
- }
- segment* Synth::getCurrentSegment(int)
- {
- if(enabled)
- {
- return segments[current_oto];
- }
- else return 0;
-
- }
- void Synth::fill(float* buffer, int size)
- {
- int cepstrum_length = 32;//FIXME
- while(1)
- {
-
- int current_samples = synth->currentTime();//time in samples
- float current_time = current_samples*1.0/samplerate;
-
- segment* seg = getCurrentSegment(current_samples);
-
- #if 1
- if(seg && current_time > seg->x[seg->count-1])
- {
- enabled=false;
- seg=0;
- }
- #endif
-
- if(seg) {
- float f0 = getCurrentF0(current_samples);
-
-
- float fractionalIndex=interp_linear(seg->x,seg->y,seg->count,current_time)*1000.0/reader->getFramePeriod();
- reader->getSegment(fractionalIndex,vvddata);
-
- float* mel_cepstrum1 = &vvddata[1];
- float* mel_cepstrum2 = &vvddata[1+cepstrum_length];
- //TODO
- // getCurrentConcatenation(current_time)
- // concatenation
- synth->setFrame(mel_cepstrum1,mel_cepstrum2,cepstrum_length);
- synth->setF0(f0);
- } else {
- synth->setSilence();
- }
-
- synth->doSynth(); //synth one frame
-
- if(synth->isFilled(size+2048)) break;
-
- }
-
- synth->pop(buffer,size);
-
-
- }
|