Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified README.md
100644 → 100755
Empty file.
2 changes: 2 additions & 0 deletions SFZero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
#include "sfzero/SFZSound.cpp"
#include "sfzero/SFZSynth.cpp"
#include "sfzero/SFZVoice.cpp"
#include "sfzero/SFZDiskStreamer.cpp"
#include "sfzero/SFZCleaner.cpp"
2 changes: 2 additions & 0 deletions SFZero.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ END_JUCE_MODULE_DECLARATION
#include "sfzero/SFZSound.h"
#include "sfzero/SFZSynth.h"
#include "sfzero/SFZVoice.h"
#include "sfzero/SFZDiskStreamer.h"
#include "sfzero/SFZCleaner.h"


#endif // INCLUDED_SFZERO_H
Expand Down
2 changes: 2 additions & 0 deletions sfzero/SF2Reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "SF2.h"
#include "SF2Generator.h"
#include "SF2Sound.h"
#include "SFZDebug.h"
#include "SFZSample.h"

sfzero::SF2Reader::SF2Reader(sfzero::SF2Sound *soundIn, const juce::File &fileIn) : sound_(soundIn)
{
Expand Down
52 changes: 52 additions & 0 deletions sfzero/SFZCleaner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
==============================================================================

SFZCleaner.cpp
Created: 4 Dec 2017 10:22:24pm
Author: malcolm

==============================================================================
*/

#include "SFZCleaner.h"

//==============================================================================
sfzero::SFZCleaner::SFZCleaner(const juce::String& threadName) : juce::Thread(threadName)
{
lastCount=-1;
}

sfzero::SFZCleaner::~SFZCleaner()
{
stopThread(3000);
checkForBuffersToFree();
}

void sfzero::SFZCleaner::run(){
while (!threadShouldExit())
{
if(lastCount!=buffers.size()){
std::cout << "cleaning " << buffers.size() << "\n";
lastCount=buffers.size();
}
checkForBuffersToFree();
wait (1000);
}
}

void sfzero::SFZCleaner::checkForBuffersToFree()
{
for (int i = buffers.size(); --i >= 0;)
{
sfzero::SFZDiskStreamer* buffer = buffers[i];
if (!buffer->isThreadRunning()){
delete buffer;
buffers.remove(i);
//std::cout << "Buffer cleaned " << buffers.size() << "\n";
}
}
}

void sfzero::SFZCleaner::addThread(SFZDiskStreamer* thread){
buffers.add(thread);
}
33 changes: 33 additions & 0 deletions sfzero/SFZCleaner.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
==============================================================================

SFZCleaner.h
Created: 4 Dec 2017 10:22:24pm
Author: malcolm

==============================================================================
*/

#ifndef SFZCLEANER_H_INCLUDED
#define SFZCLEANER_H_INCLUDED

#include "SFZDiskStreamer.h"

namespace sfzero
{
class SFZCleaner : public juce::Thread
{
public:
SFZCleaner(const juce::String& threadName);
~SFZCleaner();
void run() override;
void addThread(SFZDiskStreamer* thread);
private:
juce::Array<sfzero::SFZDiskStreamer*, juce::CriticalSection> buffers;
void checkForBuffersToFree();
int lastCount;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SFZCleaner)
};
}

#endif // SFZCLEANER_H_INCLUDED
47 changes: 47 additions & 0 deletions sfzero/SFZDiskStreamer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*************************************************************************************
* Original code copyright (C) 2012 Steve Folta
* Converted to Juce module (C) 2016 Leo Olivers
* Forked from https://github.com/stevefolta/SFZero
* For license info please see the LICENSE file distributed with this source code
*************************************************************************************/
#include "SFZDiskStreamer.h"
#include <algorithm>

sfzero::SFZDiskStreamer::SFZDiskStreamer(const juce::String& threadName, juce::File file, juce::AudioFormatManager *formatManager, int numChannels, juce::uint32 numSamples, int streamBufferSize): juce::Thread(threadName)
{
file_=file;
buffer_ = new juce::AudioSampleBuffer(numChannels, numSamples);
formatManager_=formatManager;
reader_ = formatManager_->createReaderFor(file_);
numSamplesFilled=0;
}

sfzero::SFZDiskStreamer::~SFZDiskStreamer() {
delete buffer_;
delete reader_;
}

void sfzero::SFZDiskStreamer::run(){
//std::cout << "stream " << file_.getFileName() << "\n";
int samplesToRead = std::min(blockSize_, (int)(buffer_->getNumSamples()-numSamplesFilled));
reader_->read(buffer_, numSamplesFilled, samplesToRead, numSamplesFilled, true, true);
numSamplesFilled+=samplesToRead;
}

void sfzero::SFZDiskStreamer::copyBuffer(juce::AudioSampleBuffer *inBuffer){
for(int ichnl=0; ichnl<buffer_->getNumChannels(); ichnl++)
buffer_->copyFrom(ichnl,
0, //int destStartSample,
*inBuffer, //const AudioBuffer& source,
ichnl, //int sourceChannel,
0, //int sourceStartSample,
inBuffer->getNumSamples());// int numSamples)
numSamplesFilled+=inBuffer->getNumSamples();
}

void sfzero::SFZDiskStreamer::setCurrentSample(double pos, int blockSize){
if(!isThreadRunning() && numSamplesFilled<=pos+blockSize/2){
blockSize_=blockSize;
startThread();
}
}
33 changes: 33 additions & 0 deletions sfzero/SFZDiskStreamer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*************************************************************************************
* Original code copyright (C) 2012 Steve Folta
* Converted to Juce module (C) 2016 Leo Olivers
* Forked from https://github.com/stevefolta/SFZero
* For license info please see the LICENSE file distributed with this source code
*************************************************************************************/
#ifndef SFZDISKSTREAMER_H_INCLUDED
#define SFZDISKSTREAMER_H_INCLUDED

namespace sfzero
{

class SFZDiskStreamer : public juce::Thread
{
public:
SFZDiskStreamer(const juce::String& threadName, juce::File file, juce::AudioFormatManager *formatManager, int numChannels, juce::uint32 numSamples, int streamBufferSize);
virtual ~SFZDiskStreamer();
void run() override;
juce::AudioSampleBuffer* GetVoiceBuffer(){return buffer_;}
void copyBuffer(juce::AudioSampleBuffer *buffer);
void setCurrentSample(double pos, int blockSize);
juce::uint32 getNumSamplesFilled(){return(numSamplesFilled);}
private:
juce::File file_;
juce::AudioSampleBuffer *buffer_;
juce::AudioFormatManager *formatManager_;
juce::uint32 numSamplesFilled;
juce::AudioFormatReader *reader_;
int blockSize_;
};
}

#endif // SFZDISKSTREAMER_H_INCLUDED
Empty file modified sfzero/SFZEG.cpp
100644 → 100755
Empty file.
Empty file modified sfzero/SFZReader.cpp
100644 → 100755
Empty file.
Empty file modified sfzero/SFZReader.h
100644 → 100755
Empty file.
5 changes: 3 additions & 2 deletions sfzero/SFZSample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ bool sfzero::Sample::load(juce::AudioFormatManager *formatManager)
// can be done without having to check for the edge all the time.
jassert(sampleLength_ < std::numeric_limits<int>::max());

buffer_ = new juce::AudioSampleBuffer(reader->numChannels, static_cast<int>(sampleLength_ + 4));
reader->read(buffer_, 0, static_cast<int>(sampleLength_ + 4), 0, true, true);
buffer_ = new juce::AudioSampleBuffer(reader->numChannels, static_cast<int>(preBufferSize));
reader->read(buffer_, 0, static_cast<int>(preBufferSize), 0, true, true);

juce::StringPairArray *metadata = &reader->metadataValues;
int numLoops = metadata->getValue("NumSampleLoops", "0").getIntValue();
Expand All @@ -31,6 +31,7 @@ bool sfzero::Sample::load(juce::AudioFormatManager *formatManager)
loopStart_ = metadata->getValue("Loop0Start", "0").getLargeIntValue();
loopEnd_ = metadata->getValue("Loop0End", "0").getLargeIntValue();
}
doStream_=true;
delete reader;
return true;
}
Expand Down
9 changes: 6 additions & 3 deletions sfzero/SFZSample.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ namespace sfzero
class Sample
{
public:
explicit Sample(const juce::File &fileIn) : file_(fileIn), buffer_(nullptr), sampleRate_(0), sampleLength_(0), loopStart_(0), loopEnd_(0) {}
explicit Sample(double sampleRateIn) : buffer_(nullptr), sampleRate_(sampleRateIn), sampleLength_(0), loopStart_(0), loopEnd_(0) {}
explicit Sample(const juce::File &fileIn) : file_(fileIn), buffer_(nullptr), sampleRate_(0), sampleLength_(0), loopStart_(0), loopEnd_(0), doStream_(false){}
explicit Sample(double sampleRateIn) : buffer_(nullptr), sampleRate_(sampleRateIn), sampleLength_(0), loopStart_(0), loopEnd_(0), doStream_(false) {}
virtual ~Sample();

bool load(juce::AudioFormatManager *formatManager);
Expand All @@ -31,7 +31,9 @@ class Sample
juce::uint64 getSampleLength() const { return sampleLength_; }
juce::uint64 getLoopStart() const { return loopStart_; }
juce::uint64 getLoopEnd() const { return loopEnd_; }

bool CanStream() const { return doStream_; }
static const int preBufferSize=44100;

#ifdef JUCE_DEBUG
void checkIfZeroed(const char *where);

Expand All @@ -42,6 +44,7 @@ class Sample
juce::AudioSampleBuffer *buffer_;
double sampleRate_;
juce::uint64 sampleLength_, loopStart_, loopEnd_;
bool doStream_;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Sample)
};
Expand Down
22 changes: 21 additions & 1 deletion sfzero/SFZSynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@
#include "SFZSound.h"
#include "SFZVoice.h"

sfzero::Synth::Synth() : Synthesiser() {}
sfzero::Synth::Synth() : Synthesiser() {
threadCleaner = new SFZCleaner("Cleaner");
threadCleaner->startThread(5);
for(int i=0; i<16; i++)
midiVolume_[i] = 127;
}

sfzero::Synth::~Synth(){
delete threadCleaner;
}

void sfzero::Synth::noteOn(int midiChannel, int midiNoteNumber, float velocity)
{
Expand Down Expand Up @@ -91,6 +100,7 @@ void sfzero::Synth::noteOn(int midiChannel, int midiNoteNumber, float velocity)
if (voice)
{
voice->setRegion(region);
voice->setMidiVolume(midiVolume_[midiChannel-1]);
startVoice(voice, sound, midiChannel, midiNoteNumber, velocity);
}
}
Expand Down Expand Up @@ -125,6 +135,16 @@ void sfzero::Synth::noteOff(int midiChannel, int midiNoteNumber, float velocity,
}
}

void sfzero::Synth::handleController (int midiChannel, int controllerNumber, int controllerValue)
{
switch(controllerNumber){
case 7:
midiVolume_[midiChannel-1] = controllerValue;
break;
}
Synthesiser::handleController (midiChannel, controllerNumber, controllerValue);
}

int sfzero::Synth::numVoicesUsed()
{
int numUsed = 0;
Expand Down
9 changes: 7 additions & 2 deletions sfzero/SFZSynth.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define SFZSYNTH_H_INCLUDED

#include "SFZCommon.h"
#include "SFZCleaner.h"

namespace sfzero
{
Expand All @@ -16,17 +17,21 @@ class Synth : public juce::Synthesiser
{
public:
Synth();
virtual ~Synth() {}
virtual ~Synth();

void noteOn(int midiChannel, int midiNoteNumber, float velocity) override;
void noteOff(int midiChannel, int midiNoteNumber, float velocity, bool allowTailOff) override;

void handleController (int midiChannel, int controllerNumber, int controllerValue) override;

int numVoicesUsed();
juce::String voiceInfoString();
SFZCleaner* GetCleaner(){return threadCleaner;}

private:
int noteVelocities_[128];
SFZCleaner* threadCleaner;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Synth)
int midiVolume_[16];
};
}

Expand Down
Loading