A simple string synthesizer implementing the Karplus-Strong algorithm. Licensed under the GNU LGPL.

Dependencies:   mbed

Synth.cpp

Committer:
elleo
Date:
2013-01-09
Revision:
0:ce6724069f0a

File content as of revision 0:ce6724069f0a:

/* 
 * libmbed-synth An audio synthesis library capable of running
 * alongside other activities. 
 * Copyright (C) <2009> Michael Sheldon <mike@mikeasoft.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
*/
 
#include "Synth.h"
 
Synth::Synth(PinName aout) :
        _aout(aout) {
    _repeat = false;
    _samplerate = 22000;
    _samples = NULL;
    _sample_size = 0;
    _position = 0;
    _bpm = 120;
    _notes = NULL;
    _num_notes = 0;
}

void Synth::play() {
    _ticker.attach(this, &Synth::_proc_sample, 1.0 / _samplerate);
    
    DigitalOut l(LED1);
    l = 1;
}

void Synth::pause() {
    _ticker.detach();
}

void Synth::stop() {
    _position = 0;
    _ticker.detach();
}

void Synth::set_repeat(bool repeat) {
    _repeat = repeat;
}

void Synth::set_instrument(PluckedGuitar *instrument){
    _instrument = instrument;
    _instrument->set_bpm(_bpm);
    _instrument->set_samplerate(_samplerate);
}

void Synth::set_bpm(int bpm) {
    _bpm = bpm;
    if(_instrument != NULL) {
        _instrument->set_bpm(_bpm);
    }
}

void Synth::_proc_sample() {
    if (_position == 0) {
        _instrument->note(_notes[_position]);
        _position++;
    }
    
    float sample = _instrument->proc_sample();
    
    if (sample == -1) {
        _instrument->note(_notes[_position]);
        _position++;
    } else {
        _aout = sample;
    } 
    
    if (sample == -1 && _position > _num_notes) {
        if(_repeat) {
            _position = 0;
        } else {
            stop();
        }
    }
}

void Synth::add_note(float frequency, float duration) {
    _num_notes++;
    Note n;
    n.frequency = frequency;
    n.duration = duration;
    if (_notes == NULL) {
        _notes = (Note*) malloc(sizeof(Note));
    } else {
        _notes = (Note*) realloc(_notes, sizeof(Note) * _num_notes);
        
    }
    _notes[_num_notes - 1] = n;
}