What's new

Blip_Buffer 0.4.0 Sound Synthesis Library

Blargg

New member
I've just released a long-overdue update to Blip_Buffer, my band-limited synthesis sound library, which is good for implementing things like the NES and Game Boy sound chips. You configure the clock rate and output sample rate, then generate the waveforms by specifying the timestamps (in source clocks) where the amplitude changes. It handles the rest, including adjustable treble and bass filtering. It's written in portable, conservative C++ and licensed under the GNU Lesser General Public License (LGPL). Some C programmers have used it without problem, due to its light use of C++. Examples of sound quality and programs using it are available.

Blip_Buffer-0.4.0.zip

blip_buffer.png


I've done a lot to simplify the interface and make the demos clearer. Now they play sound live and show the waveform on screen, using SDL (they can still be made to write output to a sound file for examination with a sound editor). This allows you to experiment with the code and hear/see the results immediately, and use the mouse to adjust parameters in real-time.

Code:
#include "Blip_Buffer.h"
 
// Waveform synthesizer for amplitude range of -10 to 10
static Blip_Synth<blip_good_quality,20> synth;
static Blip_Buffer buf; // Sample buffer

int main()
{
    buf.clock_rate( 1789773 ); // 1.79 MHz clock rate
    if ( buf.set_sample_rate( 48000 ) ) // 48 kHz sample rate
        return 1; // out of memory
    
    synth.output( &buf ); // output to buffer
    synth.volume( 0.50 ); // 50% volume
    
    // Generate this waveform:
    // 10                  ___
    //  5      ___        |   |
    //  0 ____|   |___    |   |________
    // -5             |   |
    //-10             |___|
    //    0   100 200 300 400 500 600 700  (time in NES clocks)
    
    synth.update( 100,   5 );
    synth.update( 200,   0 );
    synth.update( 300, -10 );
    synth.update( 400,  10 );
    synth.update( 500,   0 );
    buf.end_frame( 700 );
    
    // Read and play however many samples were generated
    blip_sample_t temp [1000];
    int count = buf.read_samples( temp, 1000 );
    play_samples( temp, count );
    
    return 0;
}

On the implementation side I trimmed the library down to just two files (header and source) and rewrote it to use an internal 32-bit sample buffer and fixed some problems with the filter kernel windowing and phase resolution, resulting in slightly better sound quality. It's based on my efficient synthesis algorithm.

Feedback welcome, especially critique.
 

Top