@@ -10,6 +10,10 @@ Envelope update - Added a filter to smooth out clicks on very fast attack levels | |||||
Scope and Meter have moved to the Input/Output group | Scope and Meter have moved to the Input/Output group | ||||
PoshSampler now has a button - ReTrigger, when this button is OFF, a sample cannot | PoshSampler now has a button - ReTrigger, when this button is OFF, a sample cannot | ||||
be retriggered until it has finished playing. | be retriggered until it has finished playing. | ||||
PoshSampler bug fixes, now displays correct settings for Loop, PingPong, ReTrigger, | |||||
Volume, Pitch, Octave, and TrigNote when you change the sample | |||||
being displayed | |||||
New pause and Reset button on GUI to pause audio and reset all plugins. | |||||
Release 0.2.2 | Release 0.2.2 | ||||
@@ -18,51 +18,81 @@ | |||||
#include "WaveChooser.h" | #include "WaveChooser.h" | ||||
#include <string> | #include <string> | ||||
#include <FL/fl_file_chooser.h> | |||||
#include <FL/Fl_File_Chooser.H> | |||||
#include "../../../config.h" | #include "../../../config.h" | ||||
using namespace std; | using namespace std; | ||||
#ifdef USE_LIBSNDFILE | #ifdef USE_LIBSNDFILE | ||||
#include <sndfile.h> | #include <sndfile.h> | ||||
#endif | #endif | ||||
char *WaveFileName (void) | |||||
{ | |||||
string AvailFmt; | |||||
// As this stands, we get one load dialog per plugin, | |||||
// I'd rather have just ONE dialog for all plugins | |||||
#ifdef USE_LIBSNDFILE | |||||
string FmtName; | |||||
SF_FORMAT_INFO info; | |||||
int major_count, m, p; | |||||
// large chunks of this are based on fl_file_chooser() from the FLTK source code | |||||
sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof (int)); | |||||
// strlcpy() and strlcat() are some really useful BSD string functions | |||||
// that work the way strncpy() and strncat() *should* have worked. | |||||
for (m = 0 ; m < major_count ; m++) | |||||
{ | |||||
info.format = m; | |||||
sf_command (NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof (info)); | |||||
FmtName = info.name; | |||||
while ((p=FmtName.find ('(')) >= 0 ) | |||||
{ | |||||
FmtName.replace (p, 1, "["); | |||||
} | |||||
while ((p=FmtName.find (')')) >= 0 ) | |||||
{ | |||||
FmtName.replace (p, 1, "]"); | |||||
} | |||||
if (!AvailFmt.empty()) | |||||
{ | |||||
AvailFmt += '\t'; | |||||
} | |||||
AvailFmt += (string)FmtName + (string)" (*." + (string)info.extension + ')'; | |||||
} | |||||
#else | |||||
AvailFmt = "{*.wav,*.WAV}"; | |||||
#endif | |||||
size_t our_strlcpy (char *dst, const char *src, size_t size) { | |||||
size_t srclen; | |||||
size--; | |||||
srclen = strlen (src); | |||||
if (srclen > size) srclen = size; | |||||
memcpy (dst, src, srclen); | |||||
dst[srclen] = '\0'; | |||||
return (srclen); | |||||
} | |||||
static Fl_File_Chooser *fc = (Fl_File_Chooser *)0; | |||||
static void (*current_callback)(const char*) = 0; | |||||
static void callback(Fl_File_Chooser *, void*) { | |||||
if (current_callback && fc->value()) (*current_callback)(fc->value()); | |||||
} | |||||
static char retname[1024]; | |||||
char *fn=fl_file_chooser("Load a sample", AvailFmt.c_str(), NULL); | |||||
return fn; | |||||
char *WaveFileName (void) { | |||||
string AvailFmt; | |||||
#ifdef USE_LIBSNDFILE | |||||
string FmtName; | |||||
SF_FORMAT_INFO info; | |||||
int major_count, m, p; | |||||
sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof (int)); | |||||
for (m = 0 ; m < major_count ; m++) { | |||||
info.format = m; | |||||
sf_command (NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof (info)); | |||||
FmtName = info.name; | |||||
while ((p=FmtName.find ('(')) >= 0 ) FmtName.replace (p, 1, "["); | |||||
while ((p=FmtName.find (')')) >= 0 ) FmtName.replace (p, 1, "]"); | |||||
if (!AvailFmt.empty()) AvailFmt += '\t'; | |||||
AvailFmt += (string)FmtName + (string)" (*." + (string)info.extension + ')'; | |||||
} | |||||
#else | |||||
AvailFmt = "{*.wav,*.WAV}"; | |||||
#endif | |||||
char *fname; | |||||
char *title = "Load a wave"; | |||||
if (!fc) { | |||||
fname = "."; | |||||
// as ever, I'm a bit worried that this is never deallocated | |||||
fc = new Fl_File_Chooser (fname, AvailFmt.c_str(), Fl_File_Chooser::CREATE, title); | |||||
fc->callback (callback, 0); | |||||
} else { | |||||
// strip away the old filename, but keep the directory | |||||
our_strlcpy (retname, fc->value(), sizeof(retname)); | |||||
char *p = strrchr(retname, '/'); | |||||
if (p) { | |||||
if (p == retname) retname[1] = '\0'; | |||||
else *p = '\0'; | |||||
} | |||||
fc->directory (retname); | |||||
} | |||||
fc->show(); | |||||
while (fc->shown()) Fl::wait(); | |||||
if (fc->value()) return (char *)fc->value(); | |||||
else return 0; | |||||
} | } |
@@ -20,18 +20,16 @@ | |||||
#include <FL/Fl_Button.h> | #include <FL/Fl_Button.h> | ||||
#include "SpiralIcon.xpm" | #include "SpiralIcon.xpm" | ||||
#include "../../NoteTable.h" | #include "../../NoteTable.h" | ||||
#include <stdio.h> | |||||
#include "../../RiffWav.h" | #include "../../RiffWav.h" | ||||
#include <stdio.h> | |||||
using namespace std; | using namespace std; | ||||
static const int NOTETRIG = NUM_SAMPLES*2+1; | |||||
static const int REC_INPUT = 16; | |||||
static const int S1_INPUT = 18; | |||||
static const int S2_INPUT = 19; | |||||
static const int S3_INPUT = 20; | |||||
static const int NOTETRIG = NUM_SAMPLES * 2 + 1; | |||||
static const int REC_INPUT = 16; | |||||
static const int S1_INPUT = 18; | |||||
static const int S2_INPUT = 19; | |||||
static const int S3_INPUT = 20; | |||||
extern "C" { | extern "C" { | ||||
SpiralPlugin* SpiralPlugin_CreateInstance() { return new PoshSamplerPlugin; } | SpiralPlugin* SpiralPlugin_CreateInstance() { return new PoshSamplerPlugin; } | ||||
@@ -42,89 +40,67 @@ extern "C" { | |||||
/////////////////////////////////////////////////////// | /////////////////////////////////////////////////////// | ||||
static void InitializeSampleDescription (SampleDesc* NewDesc, const string &Pathname, int Note) { | |||||
if (NewDesc) { | |||||
NewDesc->Pathname = Pathname; | |||||
NewDesc->Volume = 1.0f; | |||||
NewDesc->Velocity = 1.0f; | |||||
NewDesc->Pitch = 1.0f; | |||||
NewDesc->PitchMod = 1.0f; | |||||
NewDesc->SamplePos = -1; | |||||
NewDesc->Loop = false; | |||||
NewDesc->PingPong = false; | |||||
NewDesc->Note = Note; | |||||
NewDesc->Octave = 0; | |||||
NewDesc->TriggerUp = true; | |||||
NewDesc->SamplePos = -1; | |||||
NewDesc->SampleRate = 44100; | |||||
NewDesc->Stereo = false; | |||||
NewDesc->PlayStart = 0; | |||||
NewDesc->LoopStart = 0; | |||||
NewDesc->LoopEnd = INT_MAX; | |||||
NewDesc->ReTrig = true; | |||||
} | |||||
} | |||||
PoshSamplerPlugin::PoshSamplerPlugin() : | PoshSamplerPlugin::PoshSamplerPlugin() : | ||||
m_Recording(false) | m_Recording(false) | ||||
{ | { | ||||
m_PluginInfo.Name="PoshSampler"; | |||||
m_PluginInfo.Width=400; | |||||
m_PluginInfo.Height=215; | |||||
m_PluginInfo.NumInputs=21; | |||||
m_PluginInfo.NumOutputs=9; | |||||
m_PluginInfo.PortTips.push_back("Sample 1 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 1 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Sample 2 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 2 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Sample 3 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 3 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Sample 4 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 4 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Sample 5 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 5 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Sample 6 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 6 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Sample 7 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 7 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Sample 8 Pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 8 Trigger"); | |||||
m_PluginInfo.PortTips.push_back("Input"); | |||||
m_PluginInfo.PortTips.push_back("Sample trigger pitch"); | |||||
m_PluginInfo.PortTips.push_back("Sample 1 Start Pos"); | |||||
m_PluginInfo.PortTips.push_back("Sample 2 Start Pos"); | |||||
m_PluginInfo.PortTips.push_back("Sample 3 Start Pos"); | |||||
m_PluginInfo.PortTips.push_back("Mixed Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 1 Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 2 Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 3 Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 4 Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 5 Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 6 Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 7 Output"); | |||||
m_PluginInfo.PortTips.push_back("Sample 8 Output"); | |||||
for (int n=0; n<NUM_SAMPLES; n++) { | |||||
Sample* NewSample = new Sample; | |||||
m_SampleVec.push_back(NewSample); | |||||
SampleDesc* NewDesc = new SampleDesc; | |||||
char temp[256]; | |||||
sprintf (temp, "PoshSampler%d_%d", GetID(), n); | |||||
InitializeSampleDescription(NewDesc, temp, n); | |||||
m_SampleDescVec.push_back(NewDesc); | |||||
} | |||||
m_Version = 4; | |||||
m_Current = 0; | |||||
m_AudioCH->Register("Num",&m_GUIArgs.Num); | |||||
m_AudioCH->Register("Value",&m_GUIArgs.Value); | |||||
m_AudioCH->Register("Bool",&m_GUIArgs.Boole); | |||||
m_AudioCH->Register("Int",&m_GUIArgs.Int); | |||||
m_AudioCH->Register("Start",&m_GUIArgs.Start); | |||||
m_AudioCH->Register("End",&m_GUIArgs.End); | |||||
m_AudioCH->Register("LoopStart",&m_GUIArgs.LoopStart); | |||||
m_AudioCH->RegisterData("Name",ChannelHandler::INPUT,&m_GUIArgs.Name,sizeof(m_GUIArgs.Name)); | |||||
m_AudioCH->Register("PlayPos",&m_CurrentPlayPos,ChannelHandler::OUTPUT); | |||||
m_AudioCH->RegisterData("SampleBuffer",ChannelHandler::OUTPUT_REQUEST,&m_SampleBuffer,TRANSBUF_SIZE); | |||||
m_AudioCH->Register("SampleSize",&m_SampleSize,ChannelHandler::OUTPUT_REQUEST); | |||||
m_PluginInfo.Name = "PoshSampler"; | |||||
m_PluginInfo.Width = 400; | |||||
m_PluginInfo.Height = 215; | |||||
m_PluginInfo.NumInputs = 21; | |||||
m_PluginInfo.NumOutputs = 9; | |||||
m_PluginInfo.PortTips.push_back ("Sample 1 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 1 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 2 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 2 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 3 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 3 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 4 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 4 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 5 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 5 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 6 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 6 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 7 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 7 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 8 Pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 8 Trigger"); | |||||
m_PluginInfo.PortTips.push_back ("Input"); | |||||
m_PluginInfo.PortTips.push_back ("Sample trigger pitch"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 1 Start Pos"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 2 Start Pos"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 3 Start Pos"); | |||||
m_PluginInfo.PortTips.push_back ("Mixed Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 1 Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 2 Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 3 Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 4 Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 5 Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 6 Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 7 Output"); | |||||
m_PluginInfo.PortTips.push_back ("Sample 8 Output"); | |||||
for (int n=0; n<NUM_SAMPLES; n++) { | |||||
Sample* NewSample = new Sample; | |||||
m_SampleVec.push_back (NewSample); | |||||
SampleDesc* NewDesc = new SampleDesc; | |||||
InitializeSampleDescription (NewDesc, n, n); | |||||
m_SampleDescVec.push_back (NewDesc); | |||||
} | |||||
m_Version = 4; | |||||
m_Current = 0; | |||||
m_AudioCH->Register ("Num", &m_GUIArgs.Num); | |||||
m_AudioCH->Register ("Value", &m_GUIArgs.Value); | |||||
m_AudioCH->Register ("Bool", &m_GUIArgs.Boole); | |||||
m_AudioCH->Register ("Int", &m_GUIArgs.Int); | |||||
m_AudioCH->Register ("Start", &m_GUIArgs.Start); | |||||
m_AudioCH->Register ("End", &m_GUIArgs.End); | |||||
m_AudioCH->Register ("LoopStart", &m_GUIArgs.LoopStart); | |||||
m_AudioCH->RegisterData ("Name", ChannelHandler::INPUT, &m_GUIArgs.Name, sizeof (m_GUIArgs.Name)); | |||||
m_AudioCH->Register ("PlayPos", &m_CurrentPlayPos, ChannelHandler::OUTPUT); | |||||
m_AudioCH->RegisterData ("SampleBuffer", ChannelHandler::OUTPUT_REQUEST, &m_SampleBuffer, TRANSBUF_SIZE); | |||||
m_AudioCH->Register ("SampleSize", &m_SampleSize, ChannelHandler::OUTPUT_REQUEST); | |||||
m_AudioCH->Register ("BoolEcho", &m_GUIArgs.BoolEcho, ChannelHandler::OUTPUT); | |||||
m_AudioCH->Register ("ValEcho", &m_GUIArgs.ValEcho, ChannelHandler::OUTPUT); | |||||
m_AudioCH->Register ("IntEcho", &m_GUIArgs.IntEcho, ChannelHandler::OUTPUT); | |||||
} | } | ||||
PoshSamplerPlugin::~PoshSamplerPlugin() { | PoshSamplerPlugin::~PoshSamplerPlugin() { | ||||
@@ -246,10 +222,10 @@ void PoshSamplerPlugin::ExecuteCommands() { | |||||
if (m_AudioCH->IsCommandWaiting()) { | if (m_AudioCH->IsCommandWaiting()) { | ||||
switch (m_AudioCH->GetCommand()) { | switch (m_AudioCH->GetCommand()) { | ||||
case LOAD: | case LOAD: | ||||
LoadSample(m_GUIArgs.Num,m_GUIArgs.Name); | |||||
LoadSample (m_GUIArgs.Num, m_GUIArgs.Name); | |||||
break; | break; | ||||
case SAVE: | case SAVE: | ||||
SaveSample(m_GUIArgs.Num,m_GUIArgs.Name); | |||||
SaveSample (m_GUIArgs.Num, m_GUIArgs.Name); | |||||
break; | break; | ||||
case SETVOL: | case SETVOL: | ||||
m_SampleDescVec[m_GUIArgs.Num]->Volume=m_GUIArgs.Value; | m_SampleDescVec[m_GUIArgs.Num]->Volume=m_GUIArgs.Value; | ||||
@@ -306,12 +282,55 @@ void PoshSamplerPlugin::ExecuteCommands() { | |||||
m_SampleSize = m_SampleVec[m_Current]->GetLengthInBytes(); | m_SampleSize = m_SampleVec[m_Current]->GetLengthInBytes(); | ||||
break; | break; | ||||
case SETRETRIG: | case SETRETRIG: | ||||
m_SampleDescVec[m_GUIArgs.Num]->ReTrig=m_GUIArgs.Boole; | |||||
m_SampleDescVec[m_GUIArgs.Num]->ReTrig = m_GUIArgs.Boole; | |||||
break; | |||||
case GETLOOP: | |||||
m_GUIArgs.BoolEcho = m_SampleDescVec[m_Current]->Loop; | |||||
break; | |||||
case GETPING: | |||||
m_GUIArgs.BoolEcho = m_SampleDescVec[m_Current]->PingPong; | |||||
break; | |||||
case GETRETRIG: | |||||
m_GUIArgs.BoolEcho = m_SampleDescVec[m_Current]->ReTrig; | |||||
break; | |||||
case GETVOL: | |||||
m_GUIArgs.ValEcho = m_SampleDescVec[m_Current]->Volume; | |||||
break; | |||||
case GETPITCH: | |||||
m_GUIArgs.ValEcho = m_SampleDescVec[m_Current]->PitchMod; | |||||
break; | |||||
case GETOCT: | |||||
m_GUIArgs.IntEcho = m_SampleDescVec[m_Current]->Octave + 6; | |||||
break; | |||||
case GETNOTE: | |||||
m_GUIArgs.IntEcho = m_SampleDescVec[m_Current]->Note; | |||||
break; | break; | ||||
}; | }; | ||||
} | } | ||||
} | } | ||||
void PoshSamplerPlugin::InitializeSampleDescription (SampleDesc* NewDesc, int num, int Note) { | |||||
if (NewDesc) { | |||||
NewDesc->Volume = 1.0f; | |||||
NewDesc->Velocity = 1.0f; | |||||
NewDesc->Pitch = 1.0f; | |||||
NewDesc->PitchMod = 1.0f; | |||||
NewDesc->SamplePos = -1; | |||||
NewDesc->Loop = false; | |||||
NewDesc->PingPong = false; | |||||
NewDesc->Note = Note; | |||||
NewDesc->Octave = 0; | |||||
NewDesc->TriggerUp = true; | |||||
NewDesc->SamplePos = -1; | |||||
NewDesc->SampleRate = 44100; | |||||
NewDesc->Stereo = false; | |||||
NewDesc->PlayStart = 0; | |||||
NewDesc->LoopStart = 0; | |||||
NewDesc->LoopEnd = INT_MAX; | |||||
NewDesc->ReTrig = true; | |||||
} | |||||
} | |||||
void PoshSamplerPlugin::StreamOut (ostream &s) { | void PoshSamplerPlugin::StreamOut (ostream &s) { | ||||
s << m_Version << " "; | s << m_Version << " "; | ||||
for (int n=0; n<NUM_SAMPLES; n++) { | for (int n=0; n<NUM_SAMPLES; n++) { | ||||
@@ -345,32 +364,32 @@ void PoshSamplerPlugin::StreamIn (istream &s) { | |||||
m_SampleDescVec[n]->LoopStart >> | m_SampleDescVec[n]->LoopStart >> | ||||
m_SampleDescVec[n]->LoopEnd >> | m_SampleDescVec[n]->LoopEnd >> | ||||
m_SampleDescVec[n]->Note; | m_SampleDescVec[n]->Note; | ||||
if (version < 3) { | |||||
int size; | |||||
s >> size; | |||||
s.ignore (1); | |||||
char Buf[4096]; | |||||
s.get (Buf, size+1); | |||||
} | |||||
if (version > 3) s >> m_SampleDescVec[n]->ReTrig; | |||||
else m_SampleDescVec[n]->ReTrig = true; | |||||
if (version < 3) { | |||||
int size; | |||||
s >> size; | |||||
s.ignore (1); | |||||
char Buf[4096]; | |||||
s.get (Buf, size+1); | |||||
} | |||||
if (version > 3) s >> m_SampleDescVec[n]->ReTrig; | |||||
else m_SampleDescVec[n]->ReTrig = true; | |||||
} | } | ||||
} | } | ||||
void PoshSamplerPlugin::LoadSample(int n, const string &Name) | |||||
{ | |||||
WavFile Wav; | |||||
if (Wav.Open(Name,WavFile::READ)) | |||||
{ | |||||
m_SampleVec[n]->Allocate(Wav.GetSize()); | |||||
Wav.Load(*m_SampleVec[n]); | |||||
InitializeSampleDescription(m_SampleDescVec[n], Name, n); | |||||
m_SampleDescVec[n]->SampleRate=Wav.GetSamplerate(); | |||||
m_SampleDescVec[n]->Stereo=Wav.IsStereo(); | |||||
m_InitialPitch[n] = m_SampleDescVec[n]->Pitch; | |||||
m_SampleDescVec[n]->Pitch = m_InitialPitch[n] * m_SampleDescVec[n]->SampleRate/(float)m_HostInfo->SAMPLERATE; | |||||
m_SampleDescVec[n]->LoopEnd=m_SampleVec[n]->GetLength()-1; | |||||
} | |||||
void PoshSamplerPlugin::LoadSample (int n, const string &Name) { | |||||
WavFile Wav; | |||||
if (Wav.Open (Name, WavFile::READ)) { | |||||
m_SampleVec[n]->Allocate (Wav.GetSize()); | |||||
Wav.Load (*m_SampleVec[n]); | |||||
// andy preston - if this is not commented out, when we load a patch this overwrites the | |||||
// loaded data with the defaults | |||||
// InitializeSampleDescription (m_SampleDescVec[n], n, n); | |||||
m_SampleDescVec[n]->SampleRate = Wav.GetSamplerate(); | |||||
m_SampleDescVec[n]->Stereo = Wav.IsStereo(); | |||||
m_InitialPitch[n] = m_SampleDescVec[n]->Pitch; | |||||
m_SampleDescVec[n]->Pitch = m_InitialPitch[n] * m_SampleDescVec[n]->SampleRate / (float)m_HostInfo->SAMPLERATE; | |||||
m_SampleDescVec[n]->LoopEnd = m_SampleVec[n]->GetLength()-1; | |||||
} | |||||
} | } | ||||
void PoshSamplerPlugin::SaveSample(int n, const string &Name) | void PoshSamplerPlugin::SaveSample(int n, const string &Name) | ||||
@@ -429,42 +448,25 @@ void PoshSamplerPlugin::Amp(int n, long s, long e) | |||||
} | } | ||||
} | } | ||||
// The sprintf's in here should use strstream, but the current implementation (GCC 2.95.3) is buggy | |||||
bool PoshSamplerPlugin::SaveExternalFiles(const string &Dir) | |||||
{ | |||||
for (int n=0; n<NUM_SAMPLES; n++) | |||||
{ | |||||
char temp[256]; | |||||
// Andy's fix for bug 766594 | |||||
// sprintf (temp, "PoshSampler%d_%d.wav", SpiralPlugin_GetID(), n); | |||||
sprintf (temp, "PoshSampler%d_%d.wav", GetID(), n); | |||||
m_SampleDescVec[n]->Pathname = temp; | |||||
} | |||||
for (int n=0; n<NUM_SAMPLES; n++) | |||||
{ | |||||
// if it's not empty | |||||
if (m_SampleVec[n]->GetLength()!=0) | |||||
{ | |||||
SaveSample(n,Dir+m_SampleDescVec[n]->Pathname); | |||||
} | |||||
} | |||||
return true; | |||||
bool PoshSamplerPlugin::SaveExternalFiles (const string &Dir) { | |||||
char temp[256]; | |||||
for (int n=0; n<NUM_SAMPLES; n++) { | |||||
// if it's not empty | |||||
if (m_SampleVec[n]->GetLength() != 0) { | |||||
sprintf (temp, "%sPoshSampler%d_%d.wav", Dir.c_str(), GetID(), n); | |||||
SaveSample (n, temp); | |||||
} | |||||
} | |||||
return true; | |||||
} | } | ||||
void PoshSamplerPlugin::LoadExternalFiles(const string &Dir, int withID) | |||||
{ | |||||
for (int n=0; n<NUM_SAMPLES; n++) | |||||
{ | |||||
char temp[256]; | |||||
// Andy's fix for bug 766594 | |||||
// sprintf (temp, "PoshSampler%d_%d.wav", SpiralPlugin_GetID(), n); | |||||
sprintf (temp, "PoshSampler%d_%d.wav", ((withID==-1)?GetID():withID), n); | |||||
m_SampleDescVec[n]->Pathname = temp; | |||||
} | |||||
for (int n=0; n<NUM_SAMPLES; n++) | |||||
{ | |||||
LoadSample(n,Dir+m_SampleDescVec[n]->Pathname); | |||||
} | |||||
void PoshSamplerPlugin::LoadExternalFiles(const string &Dir, int withID) { | |||||
int UseID = (withID==-1) ? GetID() : withID; | |||||
char temp[256]; | |||||
for (int n=0; n<NUM_SAMPLES; n++) { | |||||
sprintf (temp, "%sPoshSampler%d_%d.wav", Dir.c_str(), UseID, n); | |||||
LoadSample (n, temp); | |||||
} | |||||
} | } |
@@ -26,7 +26,6 @@ static const int NUM_SAMPLES = 8; | |||||
static const int TRANSBUF_SIZE = 0x10000; | static const int TRANSBUF_SIZE = 0x10000; | ||||
struct SampleDesc { | struct SampleDesc { | ||||
std::string Pathname; | |||||
float Volume, Velocity, Pitch, PitchMod; | float Volume, Velocity, Pitch, PitchMod; | ||||
bool Loop, PingPong; | bool Loop, PingPong; | ||||
int Note, Octave; | int Note, Octave; | ||||
@@ -53,12 +52,12 @@ class PoshSamplerPlugin : public SpiralPlugin { | |||||
virtual void LoadExternalFiles (const std::string &Dir, int withID=-1); | virtual void LoadExternalFiles (const std::string &Dir, int withID=-1); | ||||
enum GUICommands {NONE, LOAD, SAVE, SETVOL, SETPITCH, SETLOOP, SETPING, SETNOTE, SETOCT, | enum GUICommands {NONE, LOAD, SAVE, SETVOL, SETPITCH, SETLOOP, SETPING, SETNOTE, SETOCT, | ||||
SETPLAYPOINTS, SETREC, CUT, COPY, PASTE, CROP, MIX, REV, AMP, SETCURRENT, | SETPLAYPOINTS, SETREC, CUT, COPY, PASTE, CROP, MIX, REV, AMP, SETCURRENT, | ||||
GETSAMPLE, SETRETRIG}; | |||||
GETSAMPLE, SETRETRIG, GETLOOP, GETPING, GETRETRIG, GETVOL, GETPITCH, GETOCT, | |||||
GETNOTE}; | |||||
struct GUIArgs { | struct GUIArgs { | ||||
int Num; | |||||
float Value; | |||||
bool Boole; | |||||
int Int; | |||||
int Num, Int, IntEcho; | |||||
float Value, ValEcho; | |||||
bool Boole, BoolEcho; | |||||
long Start, End, LoopStart; | long Start, End, LoopStart; | ||||
char Name[256]; | char Name[256]; | ||||
}; | }; | ||||
@@ -78,6 +77,7 @@ class PoshSamplerPlugin : public SpiralPlugin { | |||||
std::vector<Sample*> m_SampleVec; | std::vector<Sample*> m_SampleVec; | ||||
std::vector<SampleDesc*> m_SampleDescVec; | std::vector<SampleDesc*> m_SampleDescVec; | ||||
private: | private: | ||||
void InitializeSampleDescription (SampleDesc* NewDesc, int num, int Note); | |||||
void Cut (int n, long s, long e); | void Cut (int n, long s, long e); | ||||
void Copy (int n, long s, long e); | void Copy (int n, long s, long e); | ||||
void Paste (int n, long s, long e); | void Paste (int n, long s, long e); | ||||
@@ -45,10 +45,14 @@ Fl_WaveDisplay::~Fl_WaveDisplay() | |||||
{ | { | ||||
} | } | ||||
void Fl_WaveDisplay::SetSample(const float* s, long len) | |||||
{ | |||||
if (m_Sample) delete m_Sample; | |||||
m_Sample = new Sample(s,len); | |||||
void Fl_WaveDisplay::SetSample (const float *s, long len) { | |||||
if (m_Sample) delete m_Sample; | |||||
m_Sample = new Sample (s, len); | |||||
} | |||||
void Fl_WaveDisplay::ClearSample (void) { | |||||
if (m_Sample) delete m_Sample; | |||||
m_Sample = NULL; | |||||
} | } | ||||
void Fl_WaveDisplay::draw() | void Fl_WaveDisplay::draw() | ||||
@@ -178,20 +182,20 @@ int Fl_WaveDisplay::handle(int event) | |||||
if (MousePos>m_EndPos) m_EndPos=MousePos; | if (MousePos>m_EndPos) m_EndPos=MousePos; | ||||
else m_StartPos=MousePos; | else m_StartPos=MousePos; | ||||
} break; | } break; | ||||
case 1: | case 1: | ||||
{ | { | ||||
m_StartPos=MousePos; | m_StartPos=MousePos; | ||||
if (m_StartPos>m_EndPos) Holding=2; // swap | if (m_StartPos>m_EndPos) Holding=2; // swap | ||||
} break; | } break; | ||||
case 2: | case 2: | ||||
{ | { | ||||
m_EndPos=MousePos; | m_EndPos=MousePos; | ||||
if (m_StartPos>m_EndPos) Holding=1; // swap | if (m_StartPos>m_EndPos) Holding=1; // swap | ||||
} break; | } break; | ||||
case 3: m_PlayStart=MousePos; break; | case 3: m_PlayStart=MousePos; break; | ||||
case 4: m_LoopStart=MousePos; break; | case 4: m_LoopStart=MousePos; break; | ||||
case 5: m_LoopEnd=MousePos; break; | case 5: m_LoopEnd=MousePos; break; | ||||
@@ -202,41 +206,41 @@ int Fl_WaveDisplay::handle(int event) | |||||
{ | { | ||||
int Dist=(DragX-xx)*((m_ViewEnd-m_ViewStart)/w()); | int Dist=(DragX-xx)*((m_ViewEnd-m_ViewStart)/w()); | ||||
if (m_ViewStart>0 && m_ViewEnd<m_Sample->GetLength()-1) | if (m_ViewStart>0 && m_ViewEnd<m_Sample->GetLength()-1) | ||||
{ | |||||
m_ViewStart+=Dist; | |||||
{ | |||||
m_ViewStart+=Dist; | |||||
m_ViewEnd+=Dist; | m_ViewEnd+=Dist; | ||||
} | } | ||||
else // stop it sticking when at end/beginning | else // stop it sticking when at end/beginning | ||||
{ | { | ||||
if ((Dist>0 && m_ViewStart<=0) || | if ((Dist>0 && m_ViewStart<=0) || | ||||
(Dist<0 && m_ViewEnd>=m_Sample->GetLength()-1)) | |||||
(Dist<0 && m_ViewEnd>=m_Sample->GetLength()-1)) | |||||
{ | { | ||||
m_ViewStart+=Dist; | |||||
m_ViewStart+=Dist; | |||||
m_ViewEnd+=Dist; | m_ViewEnd+=Dist; | ||||
} | } | ||||
} | } | ||||
DragX=xx; | DragX=xx; | ||||
DragY=yy; | DragY=yy; | ||||
} | |||||
} | |||||
if (Mousebutton==3) | if (Mousebutton==3) | ||||
{ | { | ||||
// only draw wave at 1 pixel = 1 sample | // only draw wave at 1 pixel = 1 sample | ||||
if ((m_ViewEnd-m_ViewStart)/w()==1) | if ((m_ViewEnd-m_ViewStart)/w()==1) | ||||
{ | { | ||||
int MousePos=(xx-x())*((m_ViewEnd-m_ViewStart)/w())+m_ViewStart; | |||||
float Value=-(yy-y())/((float)h()/2.0f)+1.0f; | |||||
int MousePos=(xx-x())*((m_ViewEnd-m_ViewStart)/w())+m_ViewStart; | |||||
float Value=-(yy-y())/((float)h()/2.0f)+1.0f; | |||||
m_Sample->Set(MousePos,Value); | m_Sample->Set(MousePos,Value); | ||||
redraw(); | redraw(); | ||||
} | } | ||||
} | } | ||||
do_callback(); | do_callback(); | ||||
redraw(); | |||||
redraw(); | |||||
} | } | ||||
if (m_EndPos>=m_Sample->GetLength()) m_EndPos=m_Sample->GetLength()-1; | if (m_EndPos>=m_Sample->GetLength()) m_EndPos=m_Sample->GetLength()-1; | ||||
return 1; | return 1; | ||||
} | } | ||||
@@ -245,10 +249,10 @@ void Fl_WaveDisplay::ZoomIn() | |||||
int Zoom=(int)((m_ViewEnd-m_ViewStart)*0.03f); | int Zoom=(int)((m_ViewEnd-m_ViewStart)*0.03f); | ||||
if ((m_ViewEnd-m_ViewStart)/w()>1) | if ((m_ViewEnd-m_ViewStart)/w()>1) | ||||
{ | { | ||||
m_ViewStart+=Zoom; | |||||
m_ViewStart+=Zoom; | |||||
m_ViewEnd-=Zoom; | m_ViewEnd-=Zoom; | ||||
} | } | ||||
redraw(); | redraw(); | ||||
} | } | ||||
@@ -389,7 +393,7 @@ m_UpdateMe(false) | |||||
Info->SCOPE_SEL_COLOUR, Info->SCOPE_IND_COLOUR, Info->SCOPE_MRK_COLOUR); | Info->SCOPE_SEL_COLOUR, Info->SCOPE_IND_COLOUR, Info->SCOPE_MRK_COLOUR); | ||||
m_Display->callback((Fl_Callback*)cb_WaveDisplay); | m_Display->callback((Fl_Callback*)cb_WaveDisplay); | ||||
int bx=5,by=190,bw=w/9-2,bh=20,bs=w/9-2; | |||||
int bx=5, by=190, bw=w/9-2, bh=20, bs=w/9-2; | |||||
n=0; | n=0; | ||||
m_Cut = new Fl_Button(bx+(n++*bs),by,bw,bh,"Cut"); | m_Cut = new Fl_Button(bx+(n++*bs),by,bw,bh,"Cut"); | ||||
@@ -456,55 +460,47 @@ m_UpdateMe(false) | |||||
//m_ZoomOut->callback((Fl_Callback*)cb_ZoomOut); | //m_ZoomOut->callback((Fl_Callback*)cb_ZoomOut); | ||||
end(); | end(); | ||||
redraw(); | redraw(); | ||||
} | } | ||||
void PoshSamplerPluginGUI::UpdateSampleDisplay(int num) | |||||
{ | |||||
m_GUICH->SetCommand(PoshSamplerPlugin::GETSAMPLE); | |||||
m_GUICH->Wait(); | |||||
m_GUICH->RequestChannelAndWait("SampleSize"); | |||||
long SampleSize=m_GUICH->GetLong("SampleSize"); | |||||
if (SampleSize) | |||||
{ | |||||
char *TempBuf = new char[SampleSize]; | |||||
m_GUICH->BulkTransfer("SampleBuffer",(void*)TempBuf,SampleSize); | |||||
m_Display->SetSample((float*)TempBuf,SampleSize/sizeof(float)); | |||||
delete[] TempBuf; | |||||
} | |||||
} | |||||
void PoshSamplerPluginGUI::Update() | |||||
{ | |||||
SetPlayPos(m_GUICH->GetLong("PlayPos")); | |||||
if (m_ZoomIn->value()) m_Display->ZoomIn(); | |||||
if (m_ZoomOut->value()) m_Display->ZoomOut(); | |||||
if (m_UpdateMe) | |||||
{ | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | |||||
m_Display->redraw(); | |||||
m_UpdateMe=false; | |||||
} | |||||
//redraw(); | |||||
} | |||||
void PoshSamplerPluginGUI::UpdateValues(SpiralPlugin *o) | |||||
{ | |||||
PoshSamplerPlugin *Plugin = (PoshSamplerPlugin*)o; | |||||
m_Volume->value(Plugin->GetVolume((int)m_SampleNum->value())); | |||||
m_Pitch->value(Plugin->GetPitch((int)m_SampleNum->value())); | |||||
m_Note->value(Plugin->GetNote((int)m_SampleNum->value())); | |||||
m_Loop->value(Plugin->GetLoop((int)m_SampleNum->value())); | |||||
m_Retrig->value(Plugin->GetReTrig((int)m_SampleNum->value())); | |||||
m_UpdateMe=true; | |||||
m_Display->SetPlayStart(Plugin->GetPlayStart((int)m_SampleNum->value())); | |||||
m_Display->SetLoopStart(Plugin->GetLoopStart((int)m_SampleNum->value())); | |||||
m_Display->SetLoopEnd(Plugin->GetLoopEnd((int)m_SampleNum->value())); | |||||
m_Display->redraw(); | |||||
void PoshSamplerPluginGUI::UpdateSampleDisplay(int num) { | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETSAMPLE); | |||||
m_GUICH->Wait(); | |||||
m_GUICH->RequestChannelAndWait ("SampleSize"); | |||||
long SampleSize = m_GUICH->GetLong ("SampleSize"); | |||||
if (!SampleSize) m_Display->ClearSample(); | |||||
else { | |||||
char *TempBuf = new char[SampleSize]; | |||||
m_GUICH->BulkTransfer ("SampleBuffer", (void*)TempBuf, SampleSize); | |||||
m_Display->SetSample ((float*)TempBuf, SampleSize / sizeof(float)); | |||||
delete[] TempBuf; | |||||
} | |||||
} | |||||
void PoshSamplerPluginGUI::Update() { | |||||
SetPlayPos (m_GUICH->GetLong ("PlayPos")); | |||||
if (m_ZoomIn->value()) m_Display->ZoomIn(); | |||||
if (m_ZoomOut->value()) m_Display->ZoomOut(); | |||||
if (m_UpdateMe) { | |||||
UpdateSampleDisplay ((int)m_SampleNum->value()); | |||||
m_Display->redraw(); | |||||
m_UpdateMe=false; | |||||
} | |||||
// redraw(); | |||||
} | |||||
void PoshSamplerPluginGUI::UpdateValues (SpiralPlugin *o) { | |||||
PoshSamplerPlugin *Plugin = (PoshSamplerPlugin*)o; | |||||
m_Volume->value (Plugin->GetVolume ((int)m_SampleNum->value())); | |||||
m_Pitch->value (Plugin->GetPitch ((int)m_SampleNum->value())); | |||||
m_Note->value (Plugin->GetNote ((int)m_SampleNum->value())); | |||||
m_Loop->value (Plugin->GetLoop ((int)m_SampleNum->value())); | |||||
m_Retrig->value (Plugin->GetReTrig ((int)m_SampleNum->value())); | |||||
m_UpdateMe = true; | |||||
m_Display->SetPlayStart (Plugin->GetPlayStart ((int)m_SampleNum->value())); | |||||
m_Display->SetLoopStart (Plugin->GetLoopStart ((int)m_SampleNum->value())); | |||||
m_Display->SetLoopEnd (Plugin->GetLoopEnd ((int)m_SampleNum->value())); | |||||
m_Display->redraw(); | |||||
} | } | ||||
inline void PoshSamplerPluginGUI::cb_Load_i(Fl_Button* o, void* v) | inline void PoshSamplerPluginGUI::cb_Load_i(Fl_Button* o, void* v) | ||||
@@ -542,14 +538,15 @@ inline void PoshSamplerPluginGUI::cb_Save_i(Fl_Button* o, void* v) | |||||
void PoshSamplerPluginGUI::cb_Save(Fl_Button* o, void* v) | void PoshSamplerPluginGUI::cb_Save(Fl_Button* o, void* v) | ||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_Save_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_Save_i(o,v);} | ||||
inline void PoshSamplerPluginGUI::cb_Volume_i(Fl_Knob* o, void* v) | |||||
{ | |||||
m_GUICH->Set("Value",(float)o->value()); | |||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | |||||
m_GUICH->SetCommand(PoshSamplerPlugin::SETVOL); | |||||
inline void PoshSamplerPluginGUI::cb_Volume_i (Fl_Knob *o, void *v) { | |||||
m_GUICH->Set ("Value", (float)o->value()); | |||||
m_GUICH->Set ("Num", (int)m_SampleNum->value()); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::SETVOL); | |||||
} | |||||
void PoshSamplerPluginGUI::cb_Volume (Fl_Knob *o, void *v) { | |||||
((PoshSamplerPluginGUI*)(o->parent()))->cb_Volume_i (o, v); | |||||
} | } | ||||
void PoshSamplerPluginGUI::cb_Volume(Fl_Knob* o, void* v) | |||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_Volume_i(o,v);} | |||||
inline void PoshSamplerPluginGUI::cb_Pitch_i(Fl_Knob* o, void* v) | inline void PoshSamplerPluginGUI::cb_Pitch_i(Fl_Knob* o, void* v) | ||||
{ | { | ||||
@@ -611,7 +608,7 @@ void PoshSamplerPluginGUI::cb_PosMarker(Fl_Button* o, void* v) | |||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_PosMarker_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_PosMarker_i(o,v);} | ||||
inline void PoshSamplerPluginGUI::cb_Note_i(Fl_Counter* o, void* v) | inline void PoshSamplerPluginGUI::cb_Note_i(Fl_Counter* o, void* v) | ||||
{ | |||||
{ | |||||
m_GUICH->Set("Int",(int)o->value()); | m_GUICH->Set("Int",(int)o->value()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::SETNOTE); | m_GUICH->SetCommand(PoshSamplerPlugin::SETNOTE); | ||||
@@ -619,34 +616,55 @@ inline void PoshSamplerPluginGUI::cb_Note_i(Fl_Counter* o, void* v) | |||||
void PoshSamplerPluginGUI::cb_Note(Fl_Counter* o, void* v) | void PoshSamplerPluginGUI::cb_Note(Fl_Counter* o, void* v) | ||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_Note_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_Note_i(o,v);} | ||||
inline void PoshSamplerPluginGUI::cb_SampleNum_i(Fl_Counter* o, void* v) | |||||
{ | |||||
if (m_SampleNum->value()<0) m_SampleNum->value(0); | |||||
if (m_SampleNum->value()>7) m_SampleNum->value(7); | |||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | |||||
m_GUICH->SetCommand(PoshSamplerPlugin::SETCURRENT); | |||||
m_GUICH->Wait(); | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | |||||
inline void PoshSamplerPluginGUI::cb_SampleNum_i (Fl_Counter *o, void *v) { | |||||
if (m_SampleNum->value() < 0) m_SampleNum->value (0); | |||||
if (m_SampleNum->value() > 7) m_SampleNum->value (7); | |||||
m_GUICH->Set ("Num", (int)m_SampleNum->value()); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::SETCURRENT); | |||||
m_GUICH->Wait(); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETLOOP); | |||||
m_GUICH->Wait(); | |||||
m_Loop->value (m_GUICH->GetBool ("BoolEcho")); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETPING); | |||||
m_GUICH->Wait(); | |||||
m_PingPong->value (m_GUICH->GetBool ("BoolEcho")); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETRETRIG); | |||||
m_GUICH->Wait(); | |||||
m_Retrig->value (m_GUICH->GetBool ("BoolEcho")); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETVOL); | |||||
m_GUICH->Wait(); | |||||
m_Volume->value (m_GUICH->GetFloat ("ValEcho")); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETPITCH); | |||||
m_GUICH->Wait(); | |||||
m_Pitch->value (m_GUICH->GetFloat ("ValEcho")); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETOCT); | |||||
m_GUICH->Wait(); | |||||
m_Octave->value (m_GUICH->GetInt ("IntEcho")); | |||||
m_GUICH->SetCommand (PoshSamplerPlugin::GETNOTE); | |||||
m_GUICH->Wait(); | |||||
m_Note->value (m_GUICH->GetInt ("IntEcho")); | |||||
UpdateSampleDisplay ((int)m_SampleNum->value()); | |||||
} | |||||
void PoshSamplerPluginGUI::cb_SampleNum (Fl_Counter *o, void *v) { | |||||
((PoshSamplerPluginGUI*)(o->parent()))->cb_SampleNum_i (o, v); | |||||
} | } | ||||
void PoshSamplerPluginGUI::cb_SampleNum(Fl_Counter* o, void* v) | |||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_SampleNum_i(o,v);} | |||||
inline void PoshSamplerPluginGUI::cb_Cut_i(Fl_Button* o, void* v) | inline void PoshSamplerPluginGUI::cb_Cut_i(Fl_Button* o, void* v) | ||||
{ | |||||
{ | |||||
m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | ||||
m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::CUT); | m_GUICH->SetCommand(PoshSamplerPlugin::CUT); | ||||
m_GUICH->Wait(); | |||||
m_GUICH->Wait(); | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | UpdateSampleDisplay((int)m_SampleNum->value()); | ||||
m_Display->redraw(); | m_Display->redraw(); | ||||
} | } | ||||
void PoshSamplerPluginGUI::cb_Cut(Fl_Button* o, void* v) | void PoshSamplerPluginGUI::cb_Cut(Fl_Button* o, void* v) | ||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_Cut_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_Cut_i(o,v);} | ||||
inline void PoshSamplerPluginGUI::cb_Copy_i(Fl_Button* o, void* v) | inline void PoshSamplerPluginGUI::cb_Copy_i(Fl_Button* o, void* v) | ||||
{ | |||||
{ | |||||
m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | ||||
m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
@@ -654,27 +672,27 @@ inline void PoshSamplerPluginGUI::cb_Copy_i(Fl_Button* o, void* v) | |||||
} | } | ||||
void PoshSamplerPluginGUI::cb_Copy(Fl_Button* o, void* v) | void PoshSamplerPluginGUI::cb_Copy(Fl_Button* o, void* v) | ||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_Copy_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_Copy_i(o,v);} | ||||
inline void PoshSamplerPluginGUI::cb_Paste_i(Fl_Button* o, void* v) | inline void PoshSamplerPluginGUI::cb_Paste_i(Fl_Button* o, void* v) | ||||
{ | { | ||||
m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | ||||
m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::PASTE); | m_GUICH->SetCommand(PoshSamplerPlugin::PASTE); | ||||
m_GUICH->Wait(); | |||||
m_GUICH->Wait(); | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | UpdateSampleDisplay((int)m_SampleNum->value()); | ||||
m_Display->redraw(); | m_Display->redraw(); | ||||
} | } | ||||
void PoshSamplerPluginGUI::cb_Paste(Fl_Button* o, void* v) | void PoshSamplerPluginGUI::cb_Paste(Fl_Button* o, void* v) | ||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_Paste_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_Paste_i(o,v);} | ||||
inline void PoshSamplerPluginGUI::cb_Mix_i(Fl_Button* o, void* v) | inline void PoshSamplerPluginGUI::cb_Mix_i(Fl_Button* o, void* v) | ||||
{ | { | ||||
m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | ||||
m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::MIX); | m_GUICH->SetCommand(PoshSamplerPlugin::MIX); | ||||
m_GUICH->Wait(); | |||||
m_GUICH->Wait(); | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | UpdateSampleDisplay((int)m_SampleNum->value()); | ||||
m_Display->redraw(); | m_Display->redraw(); | ||||
} | } | ||||
@@ -687,7 +705,7 @@ inline void PoshSamplerPluginGUI::cb_Crop_i(Fl_Button* o, void* v) | |||||
m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::CROP); | m_GUICH->SetCommand(PoshSamplerPlugin::CROP); | ||||
m_GUICH->Wait(); | |||||
m_GUICH->Wait(); | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | UpdateSampleDisplay((int)m_SampleNum->value()); | ||||
m_Display->redraw(); | m_Display->redraw(); | ||||
} | } | ||||
@@ -695,12 +713,12 @@ void PoshSamplerPluginGUI::cb_Crop(Fl_Button* o, void* v) | |||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_Crop_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_Crop_i(o,v);} | ||||
inline void PoshSamplerPluginGUI::cb_Reverse_i(Fl_Button* o, void* v) | inline void PoshSamplerPluginGUI::cb_Reverse_i(Fl_Button* o, void* v) | ||||
{ | |||||
{ | |||||
m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | m_GUICH->Set("Start",(long)m_Display->GetRangeStart()); | ||||
m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::REV); | m_GUICH->SetCommand(PoshSamplerPlugin::REV); | ||||
m_GUICH->Wait(); | |||||
m_GUICH->Wait(); | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | UpdateSampleDisplay((int)m_SampleNum->value()); | ||||
m_Display->redraw(); | m_Display->redraw(); | ||||
} | } | ||||
@@ -713,7 +731,7 @@ inline void PoshSamplerPluginGUI::cb_Amp_i(Fl_Button* o, void* v) | |||||
m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | m_GUICH->Set("End",(long)m_Display->GetRangeEnd()); | ||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::AMP); | m_GUICH->SetCommand(PoshSamplerPlugin::AMP); | ||||
m_GUICH->Wait(); | |||||
m_GUICH->Wait(); | |||||
UpdateSampleDisplay((int)m_SampleNum->value()); | UpdateSampleDisplay((int)m_SampleNum->value()); | ||||
m_Display->redraw(); | m_Display->redraw(); | ||||
} | } | ||||
@@ -724,7 +742,7 @@ inline void PoshSamplerPluginGUI::cb_WaveDisplay_i(Fl_WaveDisplay* o, void* v) | |||||
{ | { | ||||
m_GUICH->Set("Start",(long)o->GetPlayStart()); | m_GUICH->Set("Start",(long)o->GetPlayStart()); | ||||
m_GUICH->Set("End",(long)o->GetLoopEnd()); | m_GUICH->Set("End",(long)o->GetLoopEnd()); | ||||
m_GUICH->Set("LoopStart",(long)o->GetLoopStart()); | |||||
m_GUICH->Set("LoopStart",(long)o->GetLoopStart()); | |||||
m_GUICH->Set("Num",(int)m_SampleNum->value()); | m_GUICH->Set("Num",(int)m_SampleNum->value()); | ||||
m_GUICH->SetCommand(PoshSamplerPlugin::SETPLAYPOINTS); | m_GUICH->SetCommand(PoshSamplerPlugin::SETPLAYPOINTS); | ||||
} | } | ||||
@@ -745,12 +763,13 @@ inline void PoshSamplerPluginGUI::cb_ZoomOut_i(Fl_Button* o, void* v) | |||||
void PoshSamplerPluginGUI::cb_ZoomOut(Fl_Button* o, void* v) | void PoshSamplerPluginGUI::cb_ZoomOut(Fl_Button* o, void* v) | ||||
{ ((PoshSamplerPluginGUI*)(o->parent()))->cb_ZoomOut_i(o,v);} | { ((PoshSamplerPluginGUI*)(o->parent()))->cb_ZoomOut_i(o,v);} | ||||
const string PoshSamplerPluginGUI::GetHelpText(const string &loc){ | const string PoshSamplerPluginGUI::GetHelpText(const string &loc){ | ||||
return string("") | |||||
return string("") | |||||
+ "A sampler that allows simple sample editing (cut copy paste etc),\n" | + "A sampler that allows simple sample editing (cut copy paste etc),\n" | ||||
+ "dirty time stretching (by modulating the start pos + retriggering +\n" | |||||
+ "dirty time stretching (by modulating the start pos + retriggering +\n" | |||||
+ "modulating pitch) and loop start/end points with ping pong loop mode.\n" | + "modulating pitch) and loop start/end points with ping pong loop mode.\n" | ||||
+ "Also implementations of controls, such as continuous pitch changing,\n" | |||||
+ "Also implementations of controls, such as continuous pitch changing,\n" | |||||
+ "so you can add portmento to samples, trigger velocity sets sample\n" | + "so you can add portmento to samples, trigger velocity sets sample\n" | ||||
+ "volume.\n\n" | + "volume.\n\n" | ||||
+ "Can records input data too.\n\n" | + "Can records input data too.\n\n" | ||||
@@ -758,7 +777,7 @@ const string PoshSamplerPluginGUI::GetHelpText(const string &loc){ | |||||
+ "lmb: Select region\n" | + "lmb: Select region\n" | ||||
+ "mmb: Move view\n" | + "mmb: Move view\n" | ||||
+ "rmb: Draws samples at full zoom.\n\n" | + "rmb: Draws samples at full zoom.\n\n" | ||||
+ "Left mouse also drags loop points. The Loop end marker defaults to the\n" | |||||
+ "Left mouse also drags loop points. The Loop end marker defaults to the\n" | |||||
+ "end of the sample.\n\n" | + "end of the sample.\n\n" | ||||
+ "Note: The loading and saving of samples is not yet realtime safe"; | + "Note: The loading and saving of samples is not yet realtime safe"; | ||||
} | } |
@@ -16,6 +16,9 @@ | |||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
*/ | */ | ||||
#ifndef POSH_SAMP_GUI_H | |||||
#define POSH_SAMP_GUI_H | |||||
#include <FL/Fl.H> | #include <FL/Fl.H> | ||||
#include <FL/Fl_Button.H> | #include <FL/Fl_Button.H> | ||||
#include <FL/Fl_Counter.H> | #include <FL/Fl_Counter.H> | ||||
@@ -23,51 +26,40 @@ | |||||
#include "../SpiralPluginGUI.h" | #include "../SpiralPluginGUI.h" | ||||
#include "../Widgets/Fl_Knob.H" | #include "../Widgets/Fl_Knob.H" | ||||
#ifndef POSH_SAMP_GUI_H | |||||
#define POSH_SAMP_GUI_H | |||||
class Fl_WaveDisplay : public Fl_Widget | |||||
{ | |||||
public: | |||||
Fl_WaveDisplay(int x,int y,int w,int h, char* Name); | |||||
~Fl_WaveDisplay(); | |||||
virtual void draw(); | |||||
virtual int handle(int event); | |||||
void SetSample(const float* s, long len); | |||||
long GetRangeStart() { return m_StartPos; } | |||||
long GetRangeEnd() { return m_EndPos; } | |||||
long GetViewStart() { return m_ViewStart; } | |||||
void SetViewStart(long s) { m_ViewStart=s; } | |||||
long GetViewEnd() { return m_ViewEnd; } | |||||
void SetViewEnd(long s) { m_ViewEnd=s; } | |||||
void SetPlayPos(long s) { m_PlayPos=s; if(m_PosMarker) redraw(); } | |||||
void SetPlayStart(long s) { m_PlayStart=s; } | |||||
long GetPlayStart() { return m_PlayStart; } | |||||
void SetLoopStart(long s) { m_LoopStart=s; } | |||||
long GetLoopStart() { return m_LoopStart; } | |||||
void SetLoopEnd(long s) { m_LoopEnd=s; } | |||||
long GetLoopEnd() { return m_LoopEnd; } | |||||
void SetPosMarker(bool s) { m_PosMarker=s; } | |||||
void ZoomIn(); | |||||
void ZoomOut(); | |||||
void SetColours (unsigned b, unsigned f, unsigned s, unsigned i, unsigned m) { | |||||
m_BGColour=(Fl_Color)b; m_FGColour=(Fl_Color)f; m_SelColour=(Fl_Color)s; | |||||
m_IndColour=(Fl_Color)i; m_MrkColour=(Fl_Color)m; | |||||
} | |||||
private: | |||||
Fl_Color m_BGColour, m_FGColour, m_SelColour, m_IndColour, m_MrkColour; | |||||
Sample *m_Sample; | |||||
long m_StartPos; | |||||
long m_EndPos; | |||||
long m_ViewStart; | |||||
long m_ViewEnd; | |||||
long m_PlayPos; | |||||
long m_PlayStart; | |||||
long m_LoopStart; | |||||
long m_LoopEnd; | |||||
bool m_PosMarker; | |||||
class Fl_WaveDisplay : public Fl_Widget { | |||||
public: | |||||
Fl_WaveDisplay (int x,int y,int w,int h, char* Name); | |||||
~Fl_WaveDisplay(); | |||||
virtual void draw(); | |||||
virtual int handle (int event); | |||||
void SetSample (const float* s, long len); | |||||
void ClearSample (void); | |||||
long GetRangeStart() { return m_StartPos; } | |||||
long GetRangeEnd() { return m_EndPos; } | |||||
long GetViewStart() { return m_ViewStart; } | |||||
void SetViewStart(long s) { m_ViewStart=s; } | |||||
long GetViewEnd() { return m_ViewEnd; } | |||||
void SetViewEnd(long s) { m_ViewEnd=s; } | |||||
void SetPlayPos(long s) { m_PlayPos=s; if(m_PosMarker) redraw(); } | |||||
void SetPlayStart(long s) { m_PlayStart=s; } | |||||
long GetPlayStart() { return m_PlayStart; } | |||||
void SetLoopStart(long s) { m_LoopStart=s; } | |||||
long GetLoopStart() { return m_LoopStart; } | |||||
void SetLoopEnd(long s) { m_LoopEnd=s; } | |||||
long GetLoopEnd() { return m_LoopEnd; } | |||||
void SetPosMarker(bool s) { m_PosMarker=s; } | |||||
void ZoomIn(); | |||||
void ZoomOut(); | |||||
void SetColours (unsigned b, unsigned f, unsigned s, unsigned i, unsigned m) { | |||||
m_BGColour=(Fl_Color)b; m_FGColour=(Fl_Color)f; m_SelColour=(Fl_Color)s; | |||||
m_IndColour=(Fl_Color)i; m_MrkColour=(Fl_Color)m; | |||||
} | |||||
private: | |||||
Fl_Color m_BGColour, m_FGColour, m_SelColour, m_IndColour, m_MrkColour; | |||||
Sample *m_Sample; | |||||
long m_StartPos, m_EndPos, m_ViewStart, m_ViewEnd; | |||||
long m_PlayPos, m_PlayStart, m_LoopStart, m_LoopEnd; | |||||
bool m_PosMarker; | |||||
}; | }; | ||||
@@ -1004,7 +1004,7 @@ iostream &SynthModular::StreamPatchIn(iostream &s, bool paste, bool merge) | |||||
if (paste || merge) | if (paste || merge) | ||||
Fl_Canvas::AppendSelection(ID, m_Canvas); | Fl_Canvas::AppendSelection(ID, m_Canvas); | ||||
else | |||||
else | |||||
if (m_NextID<=ID) m_NextID=ID+1; | if (m_NextID<=ID) m_NextID=ID+1; | ||||
} | } | ||||
@@ -1018,7 +1018,7 @@ iostream &SynthModular::StreamPatchIn(iostream &s, bool paste, bool merge) | |||||
if (paste || merge) | if (paste || merge) | ||||
{ | { | ||||
m_Copied.m_DeviceIds[ID] = m_NextID++; | m_Copied.m_DeviceIds[ID] = m_NextID++; | ||||
ID = m_Copied.m_DeviceIds[ID]; | ID = m_Copied.m_DeviceIds[ID]; | ||||
} | } | ||||