Blip_Buffer 0.4.0 Sound Synthesis Library

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Blip_Buffer 0.4.0 Sound Synthesis Library
by on (#8003)
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 APU and expansion sound chips. You configure the clock rate and output sample rate, then generate the waveforms by specifying the timestamps (in NES 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

Image

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.

by on (#8039)
In Blip_Buffer.cpp, change "assert( (i >> 31) == -1);"
to something like:

assert( (i >> (sizeof(long) * 8 - 1)) == -1);

so that it will work on platforms that have 64-bit longs.

-Mednafen