Ticket #9920: 0001-BSynth-upgrade-synth.sf2-search-Reverb-and-GetAudio.patch

File 0001-BSynth-upgrade-synth.sf2-search-Reverb-and-GetAudio.patch, 6.8 KB (added by Pete, 11 years ago)

Enhancement patch to BSynth

  • headers/os/midi/MidiDefs.h

    From 281d46c3b45d170a3cff0470cbcb1be8911fa181 Mon Sep 17 00:00:00 2001
    From: Pete Goodeve <pete.goodeve@computer.org>
    Date: Sun, 11 Aug 2013 22:17:15 -0700
    Subject: [PATCH] BSynth upgrade: synth.sf2 search, Reverb, and GetAudio
    
    ---
     headers/os/midi/MidiDefs.h  |    6 ++--
     src/kits/midi/SoftSynth.cpp |   70 +++++++++++++++++++++++++++++++++++++++----
     src/kits/midi/SoftSynth.h   |    7 ++++-
     src/kits/midi/Synth.cpp     |   20 +++++++++----
     4 files changed, 89 insertions(+), 14 deletions(-)
    
    diff --git a/headers/os/midi/MidiDefs.h b/headers/os/midi/MidiDefs.h
    index a4d44c5..10cd0f4 100644
    a b  
    1313//------------------------------------------------------------------------------
    1414
    1515/* Synthesizer things */
    16 
    17 #define B_SYNTH_DIRECTORY    B_SYSTEM_DATA_DIRECTORY
     16#define B_SYNTH_DIRECTORY    B_COMMON_DATA_DIRECTORY
     17#define B_SYNTH_FILE     "synth/synth.sf2"
     18/* Deprecated BeOS-era naming: */
     19#define B_OLD_SYNTH_DIRECTORY    B_SYSTEM_DATA_DIRECTORY
    1820#define B_BIG_SYNTH_FILE     "synth/big_synth.sy"
    1921#define B_LITTLE_SYNTH_FILE  "synth/little_synth.sy"
    2022
  • src/kits/midi/SoftSynth.cpp

    diff --git a/src/kits/midi/SoftSynth.cpp b/src/kits/midi/SoftSynth.cpp
    index 9bcc757..881c005 100644
    a b  
    11/*
    2  * Copyright 2006, Haiku.
     2 * Copyright 2006-2013, Haiku.
    33 *
    44 * Copyright (c) 2004-2005 Matthijs Hollemans
    55 * Copyright (c) 2003 Jerome Leveque
     
    99 *      Jérôme Duval
    1010 *      Jérôme Leveque
    1111 *      Matthijs Hollemans
     12 *      Pete Goodeve
    1213 */
    1314
    1415#include <MidiRoster.h>
    1516#include <MidiConsumer.h>
     17#include <File.h>
    1618#include <FindDirectory.h>
    1719#include <Path.h>
    1820#include <string.h>
    BSoftSynth::BSoftSynth()  
    2931:   fInitCheck(false),
    3032    fSynth(NULL),
    3133    fSettings(NULL),
     34    fMonitor(NULL),
     35    fMonitorSize(0),
    3236    fSoundPlayer(NULL)
    3337{
    3438    fInstrumentsFile = NULL;
    BSoftSynth::~BSoftSynth()  
    5256    // didn't release our endpoints.
    5357
    5458    Unload();
     59    delete fMonitor;
    5560}
    5661
    5762
    status_t  
    8489BSoftSynth::SetDefaultInstrumentsFile()
    8590{
    8691    BPath path;
    87     if (B_OK == find_directory(B_SYNTH_DIRECTORY, &path, false, NULL)) {
     92    status_t res = B_ERROR;
     93
     94    // Look for user specified SoundFont first:
     95    if (find_directory(B_USER_SETTINGS_DIRECTORY, &path, false, NULL) == B_OK) {
     96        path.Append(B_SYNTH_FILE);
     97        res = SetInstrumentsFile(path.Path());
     98    }
     99   
     100    // Otherwise check for defaults:
     101    if (res != B_OK && find_directory(B_USER_DATA_DIRECTORY, &path, false, NULL) == B_OK) {
     102        path.Append(B_SYNTH_FILE);
     103        res = SetInstrumentsFile(path.Path());
     104    }
     105   
     106    if (res != B_OK && find_directory(B_SYNTH_DIRECTORY, &path, false, NULL) == B_OK) {
     107        path.Append(B_SYNTH_FILE);
     108        res = SetInstrumentsFile(path.Path());
     109    }
     110   
     111    // If nothing else, try old naming convention:
     112    if (res != B_OK && find_directory(B_SYSTEM_DATA_DIRECTORY, &path, false, NULL) == B_OK) {
    88113        path.Append(B_BIG_SYNTH_FILE);
    89         return SetInstrumentsFile(path.Path());
     114        res = SetInstrumentsFile(path.Path());
    90115    }
    91116   
    92     return B_ERROR;
     117    if (res != B_OK)
     118        fprintf(stderr, "No Soundfont found\n");
     119
     120    return res;
    93121}
    94122
    95123
    BSoftSynth::SetInstrumentsFile(const char* path)  
    98126{
    99127    if (path == NULL)
    100128        return B_BAD_VALUE;
     129    BFile test;
     130    status_t res = test.SetTo(path, B_READ_ONLY);
     131    if (res != B_OK)
     132        return res;
    101133   
    102134    if (IsLoaded())
    103135        Unload();
    BSoftSynth::IsReverbEnabled() const  
    216248}
    217249
    218250
     251struct ReverbSettings {
     252    double room, damp, width, level;
     253} gReverbSettings[] = {
     254    {0.0, 0.0, 0.0, 0.0},   //  Dummy (table starts at 1)
     255    {0.0, 0.0, 0.0, 0.0},   //  B_REVERB_NONE
     256    {0.2, 0.0, 0.5, 0.9},   //  B_REVERB_CLOSET
     257    {0.5, 0.0, 0.9, 0.9},   //  B_REVERB_GARAGE
     258    {0.7, 0.25, 0.9, 0.95}, //  B_REVERB_BALLROOM
     259    {0.99, 0.3, 1.0, 1.0},  //  B_REVERB_CAVERN
     260    {1.03, 0.6, 1.0, 1.0}   //  B_REVERB_DUNGEON
     261};
     262
     263
    219264void
    220265BSoftSynth::SetReverb(reverb_mode mode)
    221266{
    222     // TODO: this function could change depending on the synth back-end.
    223 
     267    if (mode < B_REVERB_NONE || mode > B_REVERB_DUNGEON)
     268        return;
    224269    fReverbMode = mode;
     270    if (fSynth) {
     271        ReverbSettings *rvb = &gReverbSettings[mode];
     272        fluid_synth_set_reverb(fSynth, rvb->room, rvb->damp, rvb->width, rvb->level);
     273    }
    225274}
    226275
    227276
    BSoftSynth::_Init()  
    444493        fprintf(stderr, "error in fluid_synth_sfload\n");
    445494        return;
    446495    }
     496   
     497    SetReverb(fReverbMode);
    447498
    448499    media_raw_audio_format format = media_raw_audio_format::wildcard;
    449500    format.channel_count = 2;
    BSoftSynth::PlayBuffer(void * cookie, void * data, size_t size, const media_raw_  
    491542
    492543    // we use float samples
    493544   
     545    if (synth->fMonitorSize == 0) {
     546        synth->fMonitor = (float *)new void *[size];
     547        synth->fMonitorSize = size;
     548        synth->fMonitorChans = format.channel_count;
     549    }
     550   
    494551    if (synth->fSynth)
    495552        fluid_synth_write_float(synth->fSynth, size / sizeof(float) / format.channel_count,
    496553            data, 0, format.channel_count,
    497554            data, 1, format.channel_count);
     555    memcpy(synth->fMonitor, data, size);
    498556}
    499557
  • src/kits/midi/SoftSynth.h

    diff --git a/src/kits/midi/SoftSynth.h b/src/kits/midi/SoftSynth.h
    index 1e162d3..8de5a82 100644
    a b  
    11/*
    2  * Copyright 2006, Haiku.
     2 * Copyright 2006-2013, Haiku.
    33 *
    44 * Copyright (c) 2004-2005 Matthijs Hollemans
    55 * Copyright (c) 2003 Jerome Leveque
     
    99 *      Jérôme Duval
    1010 *      Jérôme Leveque
    1111 *      Matthijs Hollemans
     12 *      Pete Goodeve
    1213 */
    1314
    1415#ifndef _SOFT_SYNTH_H
    private:  
    106107
    107108    fluid_synth_t *fSynth;
    108109    fluid_settings_t* fSettings;
     110   
     111    float *fMonitor;
     112    size_t fMonitorSize;
     113    int16 fMonitorChans;
    109114
    110115    BSoundPlayer *fSoundPlayer;
    111116};
  • src/kits/midi/Synth.cpp

    diff --git a/src/kits/midi/Synth.cpp b/src/kits/midi/Synth.cpp
    index 8f64d9f..b7d8c0b 100644
    a b  
    11/*
    2  * Copyright 2006, Haiku.
     2 * Copyright 2006-2013, Haiku.
    33 *
    44 * Copyright (c) 2002-2004 Matthijs Hollemans
    55 * Copyright (c) 2003 Jerome Leveque
     
    88 * Authors:
    99 *      Jérôme Leveque
    1010 *      Matthijs Hollemans
     11 *      Pete Goodeve
    1112 */
    1213
    1314#include <string.h>
    BSynth::SampleVolume(void) const  
    218219status_t
    219220BSynth::GetAudio(int16* pLeft, int16* pRight, int32 max_samples) const
    220221{
    221     // We don't print a "not supported" message here. That would cause
    222     // significant slowdowns because applications ask for this many times.
    223    
     222    if (fSynth->fMonitorSize > 0) {
     223        int32 nSamples = fSynth->fMonitorSize / sizeof(float) / fSynth->fMonitorChans;
     224        if (nSamples > max_samples)
     225            nSamples = max_samples;
     226        float *sPtr = fSynth->fMonitor;
     227        for (int32 i = 0; i < nSamples; i++, sPtr += fSynth->fMonitorChans) {
     228            *pLeft++ = (int16)(*sPtr * 32768);
     229            *pRight++ = (int16)(*(sPtr+1) * 32768);
     230        }
     231        return nSamples;
     232    }
     233
     234    // Just in case there's no data:   
    224235    memset(pLeft, 0, max_samples * sizeof(int16));
    225236    memset(pRight, 0, max_samples * sizeof(int16));
    226    
    227237    return max_samples;
    228238}
    229239