123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #include "synth.hpp"
- #include <fstream>
- #include <iostream>
- #include <assert.h>
- #include <math.h>
- #include <sekai/common.h>
- #include <sekai/mfcc.h>
- #include <sndfile.h>
- #include <stdlib.h> /* srand, rand */
- #define TWOPI (2 * M_PI)
- #define IMP_LENGTH_MAX (1024 * 8)
- 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.0 * pow(2, (double)(m - 69.0) / 12.0);
- }
- Synth::Synth() {
- VoiceDefESPEAK* def = new VoiceDefESPEAK("autobahn.pho");
- for (int i = 0; i < MAX_POLYPHONY; i++) {
- key[i] = 0;
- freq[i] = 0;
- voice[i] = new SynthRT();
- voice[i]->voicedef = def;
- voice[i]->impulse_response = new float[IMP_LENGTH_MAX];
- voice[i]->samplerate = 0;
- }
-
-
-
-
-
- }
- void Synth::init(int samplerate, int buffer_size) {
- this->samplerate = samplerate;
- this->buffer_size = buffer_size;
- for (int i = 0; i < MAX_POLYPHONY; i++) {
- voice[i]->samplerate = samplerate;
- }
- }
- Synth::~Synth() {}
- void Synth::noteOn(int notenum, int velocity) {
- for (int i = 0; i < MAX_POLYPHONY; i++) {
- if (freq[i] == 0) {
- freq[i] = midi_freq(notenum + bend);
- key[i] = notenum;
- if (i > 0)
- voice[i]->setInputPositionSamples(voice[0]->inputPositionSamples());
- active_keys++;
- break;
- }
- }
- }
- void Synth::noteOff(int notenum) {
- for (int i = 0; i < MAX_POLYPHONY; i++) {
- if (key[i] == notenum) {
- freq[i] = 0;
- key[i] = 0;
- voice[i]->reset();
- voice[i]->setInputPositionSamples(0);
- active_keys--;
- break;
- }
- }
- }
- void Synth::controllerEvent(int a1, int a2) {
- if (a1 == 1) speed = 128 - a2;
- }
- void Synth::pitchBend(int a1, int a2) {
- float fract = 1.0 * (a2 * 128 + a1 - 8 * 1024) / (8 * 1024);
- bend = fract;
- for (int i = 0; i < MAX_POLYPHONY; i++) {
- if (freq[i]) freq[i] = midi_freq(key[i] + bend);
- }
- }
- void Synth::fill(float *buffer, int size) {
- for (int i = 0; i < size; i++) buffer[i] = 0;
- static int size2=size;
- for (int i = 0; i < MAX_POLYPHONY; i++) {
- if (key[i]) {
- float T0 = (samplerate / freq[i]);
- voice[i]->period = T0;
- voice[i]->enabled = true;
- }
- else
- {
- voice[i]->period = 10;
- voice[i]->enabled = false;
- }
- }
- float buffer_tmp[size];
- for (int i = 0; i < MAX_POLYPHONY; i++) {
- voice[i]->readData(buffer_tmp,size,size2);
- for (int j = 0; j < size; j++) buffer[j] += buffer_tmp[j];
- }
-
-
- if(active_keys) {
- for (int i = 0; i < size; i++) buffer[i] /= active_keys;
- }
- }
- static const int olabuffer_length=1024*8;
- SynthRT::SynthRT() : VoiceSampler(olabuffer_length)
- {
-
- }
- bool SynthRT::addOnePulse()
- {
- if(enabled)
- {
- float factor = 0.25;
- float pos = inputPositionSamples() * factor / samplerate;
- voicedef->getImpulseResponse(pos,impulse_response,&impulse_response_length,0);
- printf("pos %f impulse_response_length %i\n",pos,impulse_response_length);
- hanningWindow(impulse_response,impulse_response_length);
- ola(impulse_response,impulse_response_length,period);
- }
- else
- {
- float dummy=0;
- ola(&dummy,1,10);
- }
-
- return true;
- }
|