summaryrefslogtreecommitdiff
path: root/muse2/synti/simpledrums2/simpledrums.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/synti/simpledrums2/simpledrums.cpp')
-rw-r--r--muse2/synti/simpledrums2/simpledrums.cpp252
1 files changed, 183 insertions, 69 deletions
diff --git a/muse2/synti/simpledrums2/simpledrums.cpp b/muse2/synti/simpledrums2/simpledrums.cpp
index a723c133..a0d2b75b 100644
--- a/muse2/synti/simpledrums2/simpledrums.cpp
+++ b/muse2/synti/simpledrums2/simpledrums.cpp
@@ -88,6 +88,46 @@ int SS_map_logdomain2pluginparam(float pluginparam_log)
return scaled;
}
+double rangeToPitch(int value)
+{
+ // inrange 0 .. 127
+ // outrange 0.5 .. 2
+ double outValue;
+ if (value == 64)
+ outValue = 1.0;
+ else if (value > 64) {
+ outValue = double(value) / 64.0;
+ }
+ else { // value < 63
+ outValue = double(value) / 127.0 + 0.5;
+ }
+
+ //printf("rangeToPitch(%d) %f\n", value, outValue);
+ return outValue;
+}
+
+/*int pitchToRange(double pitch)
+{
+ // inrange 0.5 .. 2
+ // outrange 0 .. 127
+ int outValue;
+ if (fabs(pitch -1.0) < 0.0001)
+ outValue = 64;
+ else if ( pitch < 1.0){
+ outValue = (pitch -0.5) * 127;
+ }
+ else if ( pitch > 1.0) {
+ outValue = (pitch -1.0) * 127 + 32;
+ }
+ if (outValue < 0)
+ outValue = 0;
+ if (outValue > 127)
+ outValue = 127;
+ printf("pitchToRange(%f) %d\n", pitch, outValue);
+ return outValue;
+}*/
+
+
//---------------------------------------------------------
// SimpleSynth
//---------------------------------------------------------
@@ -108,6 +148,7 @@ SimpleSynth::SimpleSynth(int sr)
//initialize
for (int i=0; i<SS_NR_OF_CHANNELS; i++) {
channels[i].sample = 0;
+ channels[i].originalSample = 0;
channels[i].playoffset = 0;
channels[i].noteoff_ignore = false;
channels[i].volume = (double) (100.0/SS_CHANNEL_VOLUME_QUOT );
@@ -115,6 +156,7 @@ SimpleSynth::SimpleSynth(int sr)
channels[i].pan = 64;
channels[i].balanceFactorL = 1.0;
channels[i].balanceFactorR = 1.0;
+ channels[i].pitchInt = 64;
SWITCH_CHAN_STATE(i, SS_CHANNEL_INACTIVE);
channels[i].channel_on = false;
for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) {
@@ -421,6 +463,19 @@ bool SimpleSynth::setController(int channel, int id, int val)
channels[ch].volume_ctrlval = val;
updateVolume(ch, val);
break;
+ case SS_CHANNEL_CTRL_PITCH:
+ if (SS_DEBUG_MIDI)
+ printf("Received channel ctrl pitch %d for channel %d\n", val, ch);
+ channels[ch].pitchInt = val;
+ printf("SS_CHANNEL_CTRL_PITCH %d\n", channels[channel].pitchInt);
+
+ if (channels[ch].sample != 0)
+ {
+ std::string bkStr = channels[ch].sample->filename;
+ resample(channels[ch].originalSample,channels[ch].sample,rangeToPitch(channels[ch].pitchInt));
+ }
+ break;
+
case SS_CHANNEL_CTRL_NOFF:
if (SS_DEBUG_MIDI)
printf("Received ctrl noff %d for channel %d\n", val, ch);
@@ -538,7 +593,7 @@ bool SimpleSynth::sysex(int len, const unsigned char* d)
if(len < 3 || d[0] != MUSE_SYNTH_SYSEX_MFG_ID
|| d[1] != SIMPLEDRUMS_UNIQUE_ID)
{
- if (SS_DEBUG_MIDI)
+ //if (SS_DEBUG_MIDI)
printf("MusE SimpleDrums: Unknown sysex header\n");
return false;
}
@@ -546,7 +601,9 @@ bool SimpleSynth::sysex(int len, const unsigned char* d)
const unsigned char* data = d + 2;
SS_TRACE_IN
int cmd = data[0];
+ printf("Got sysex %d %d\n", len, cmd );
switch (cmd) {
+
case SS_SYSEX_LOAD_SAMPLE:
{
int channel = data[1];
@@ -558,6 +615,17 @@ bool SimpleSynth::sysex(int len, const unsigned char* d)
loadSample(channel, filename);
break;
}
+ case SS_SYSEX_PITCH_SAMPLE:
+ {
+ int channel = data[1];
+ channels[channel].pitchInt = data[2];
+
+ printf("SS_SYSEX_PITCH_SAMPLE %d\n", channels[channel].pitchInt);
+
+ //if (strlen(channels[channel].name) > 0)
+ // loadSample(channel, channels[channel].name);
+ break;
+ }
case SS_SYSEX_CLEAR_SAMPLE:
{
int ch = data[1];
@@ -1008,8 +1076,9 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data)
// 2 - noff ignore (0-1)
// 3 - channel on/off (0-1)
// 4 - 7 - sendfx 1-4 (0-127)
- // 8 - len of filename, n
- // 9 - 9+n - filename
+ // 8 - pitch
+ // 9 - len of filename, n
+ // 10 - 10+n - filename
for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) {
initBuffer[i] = (byte) channels[ch].volume_ctrlval;
initBuffer[i+1] = (byte) channels[ch].pan;
@@ -1019,6 +1088,7 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data)
initBuffer[i+5] = (byte) round(channels[ch].sendfxlevel[1] * 127.0);
initBuffer[i+6] = (byte) round(channels[ch].sendfxlevel[2] * 127.0);
initBuffer[i+7] = (byte) round(channels[ch].sendfxlevel[3] * 127.0);
+ initBuffer[i+8] = channels[ch].pitchInt;
if (SS_DEBUG_INIT) {
printf("Channel %d:\n", ch);
@@ -1032,12 +1102,12 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data)
}
if (channels[ch].sample) {
int filenamelen = strlen(channels[ch].sample->filename.c_str()) + 1;
- initBuffer[i+8] = (byte) filenamelen;
- memcpy((initBuffer+(i+9)), channels[ch].sample->filename.c_str(), filenamelen);
+ initBuffer[i+9] = (byte) filenamelen;
+ memcpy((initBuffer+(i+10)), channels[ch].sample->filename.c_str(), filenamelen);
if (SS_DEBUG_INIT) {
- printf("initBuffer[%d] - filenamelen: %d\n", i+8, filenamelen);
- printf("initBuffer[%d] - initBuffer[%d] - filename: ", (i+9), (i+9) + filenamelen - 1);
- for (int j = i+9; j< i+9+filenamelen; j++) {
+ printf("initBuffer[%d] - filenamelen: %d\n", i+9, filenamelen);
+ printf("initBuffer[%d] - initBuffer[%d] - filename: ", (i+10), (i+10) + filenamelen - 1);
+ for (int j = i+10; j< i+10+filenamelen; j++) {
printf("%c",initBuffer[j]);
}
printf("\n");
@@ -1045,9 +1115,9 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data)
i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1 + filenamelen);
}
else {
- initBuffer[i+8] = SS_NO_SAMPLE;
+ initBuffer[i+9] = SS_NO_SAMPLE;
if (SS_DEBUG_INIT) {
- printf("initBuffer[%d]: SS_NO_SAMPLE: - %d\n", i+8, SS_NO_SAMPLE);
+ printf("initBuffer[%d]: SS_NO_SAMPLE: - %d\n", i+9, SS_NO_SAMPLE);
}
i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1);
}
@@ -1152,9 +1222,11 @@ void SimpleSynth::parseInitData(const unsigned char* data)
{
SS_TRACE_IN
//int len = strlen((const char*)data);
- if (SS_DEBUG_INIT) {
+ //if (SS_DEBUG_INIT)
+ {
printf("buffer[1], SS_SYSEX_INIT_DATA_VERSION=%d\n", *(data+1));
}
+ int dataVersion = *(data+1);
const byte* ptr = data+2;
for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) {
channels[ch].volume_ctrlval = (byte) *(ptr);
@@ -1196,6 +1268,15 @@ void SimpleSynth::parseInitData(const unsigned char* data)
ptr++;
}
+//
+//
+//
+ if (dataVersion > 1) {
+ updatePitch(ch, *(ptr));
+ guiUpdatePitch(ch, *(ptr));
+ ptr++;
+ }
+
bool hasSample = *(ptr);
ptr++;
@@ -1346,7 +1427,7 @@ bool SimpleSynth::loadSample(int chno, const char* filename)
}
else
{
- //printf("current path: %s \nmuseProject %s\nfilename %s\n",QDir::currentPath().toLatin1().data(), MusEGlobal::museProject.toLatin1().data(), filename);
+ printf("current path: %s \nmuseProject %s\nfilename %s\n",QDir::currentPath().toLatin1().data(), MusEGlobal::museProject.toLatin1().data(), filename);
//MusEGlobal::museProject
QFileInfo fi(filename);
if (QFile::exists(fi.fileName()))
@@ -1382,6 +1463,48 @@ bool SimpleSynth::loadSample(int chno, const char* filename)
return true;
}
+
+void resample(SS_Sample *origSample, SS_Sample* newSample, double pitch)
+{
+ // Get new nr of frames:
+ double srcratio = (double) SS_samplerate/ (double) origSample->samplerate * pitch;
+ newSample->frames = (long) floor(((double) origSample->frames * srcratio));
+ //smp->frames = (sfi.channels == 1 ? smp->frames * 2 : smp->frames ); // Double nr of new frames if mono->stereo
+ newSample->samples = newSample->frames * newSample->channels;
+ newSample->samplerate = SS_samplerate;
+
+ // Allocate mem for the new one
+ float* newData = new float[newSample->frames * newSample->channels];
+ memset(newData, 0, sizeof(float)* newSample->frames * newSample->channels);
+
+ // libsamplerate & co (secret rabbits in the code!)
+ SRC_DATA srcdata;
+ srcdata.data_in = origSample->data;
+ srcdata.data_out = newData;
+ srcdata.input_frames = origSample->frames;
+ srcdata.output_frames = newSample->frames;
+ srcdata.src_ratio = (double) newSample->samplerate / (double) origSample->samplerate * pitch;
+
+ if (SS_DEBUG) {
+ printf("Converting sample....\n");
+ }
+
+ if (src_simple(&srcdata, SRC_SINC_BEST_QUALITY, origSample->channels)) {
+ SS_ERROR("Error when resampling, ignoring current sample");
+ //TODO: deallocate and stuff
+ }
+ else if (SS_DEBUG) {
+ printf("Sample converted. %ld input frames used, %ld output frames generated\n",
+ srcdata.input_frames_used,
+ srcdata.output_frames_gen);
+ }
+ float *oldData = newSample->data;
+ newSample->data = newData;
+ if (oldData) {
+ delete oldData;
+ }
+}
+
/*!
\fn loadSampleThread(void* p)
\brief Since process needs to respond withing a certain time, loading of samples need to be done in a separate thread
@@ -1402,8 +1525,6 @@ static void* loadSampleThread(void* p)
delete[] ch->sample->data;
delete ch->sample;
}
- ch->sample = new SS_Sample;
- SS_Sample* smp = ch->sample;
SNDFILE* sf;
const char* filename = loader->filename.c_str();
@@ -1436,40 +1557,31 @@ static void* loadSampleThread(void* p)
// Allocate and read the thingie
//
- // If current samplerate is the same as MusE's:
- if (SS_samplerate == sfi.samplerate) {
- smp->data = new float[sfi.channels * sfi.frames];
- sf_count_t n = sf_readf_float(sf, smp->data, sfi.frames);
- smp->frames = sfi.frames;
- smp->samples = (n * sfi.channels);
- smp->channels = sfi.channels;
- if (SS_DEBUG) {
- printf("%ld frames read\n", (long) n);
- }
- }
- else // otherwise, resample:
+// // If current samplerate is the same as MusE's and no pitching is needed:
+// if (SS_samplerate == sfi.samplerate && (ch->pitch -1.0) < 0.001) {
+// smp->data = new float[sfi.channels * sfi.frames];
+// sf_count_t n = sf_readf_float(sf, smp->data, sfi.frames);
+// smp->frames = sfi.frames;
+// smp->samples = (n * sfi.channels);
+// smp->channels = sfi.channels;
+// if (SS_DEBUG) {
+// printf("%ld frames read\n", (long) n);
+// }
+// }
+// else // otherwise, resample:
{
- smp->channels = sfi.channels;
- // Get new nr of frames:
- double srcratio = (double) SS_samplerate/ (double) sfi.samplerate;
- smp->frames = (long) floor(((double) sfi.frames * srcratio));
- smp->frames = (sfi.channels == 1 ? smp->frames * 2 : smp->frames ); // Double nr of new frames if mono->stereo
- smp->samples = smp->frames * smp->channels;
+ ch->sample = new SS_Sample;
+ SS_Sample* smp = ch->sample;
+ //smp->data = 0; // reset the data so we won't accidentally delete unallocated data
+ ch->originalSample = new SS_Sample;
+ SS_Sample* origSmp = ch->originalSample;
- if (SS_DEBUG) {
- //wilyfoobar-2011-02-13
- // arg2 :sfi.frames is of type sf_count_t (== 64 bit) (long long)
- // this requires format %lld (twice 'l' in format string (arg1)
- // old code//printf("Resampling from %ld frames to %ld frames - srcration: %lf\n", sfi.frames, smp->frames, srcratio);
- //printf("Resampling from %lld frames to %ld frames - srcration: %lf\n", sfi.frames, smp->frames, srcratio);
- // Changed by Tim. Just avoid the hassle for now. Need to determine 32/64 bit and provide two different printf lines.
- printf("Resampling to %ld frames - srcration: %lf\n", smp->frames, srcratio);
- printf("Nr of new samples: %ld\n", smp->samples);
- }
+ smp->channels = sfi.channels;
+ origSmp->channels = sfi.channels;
- // Read to temporary:
- float temp[sfi.frames * sfi.channels];
- int frames_read = sf_readf_float(sf, temp, sfi.frames);
+ // Read to original sample storage:
+ float *origSample = new float[sfi.frames * sfi.channels];
+ int frames_read = sf_readf_float(sf, origSample, sfi.frames);
if (frames_read != sfi.frames) {
fprintf(stderr,"Error reading sample %s\n", filename);
simplesynth_ptr->guiSendSampleLoaded(false, loader->ch_no, filename);
@@ -1482,31 +1594,12 @@ static void* loadSampleThread(void* p)
SS_TRACE_OUT
}
- // Allocate mem for the new one
- smp->data = new float[smp->frames * smp->channels];
- memset(smp->data, 0, sizeof(float)* smp->frames * smp->channels);
-
- // libsamplerate & co (secret rabbits in the code!)
- SRC_DATA srcdata;
- srcdata.data_in = temp;
- srcdata.data_out = smp->data;
- srcdata.input_frames = sfi.frames;
- srcdata.output_frames = smp->frames;
- srcdata.src_ratio = (double) SS_samplerate / (double) sfi.samplerate;
+ origSmp->channels = sfi.channels;
+ origSmp->frames = sfi.frames;
+ origSmp->samplerate = sfi.samplerate;
+ origSmp->data = origSample;
- if (SS_DEBUG) {
- printf("Converting sample....\n");
- }
-
- if (src_simple(&srcdata, SRC_SINC_BEST_QUALITY, sfi.channels)) {
- SS_ERROR("Error when resampling, ignoring current sample");
- //TODO: deallocate and stuff
- }
- else if (SS_DEBUG) {
- printf("Sample converted. %ld input frames used, %ld output frames generated\n",
- srcdata.input_frames_used,
- srcdata.output_frames_gen);
- }
+ resample(origSmp, smp, rangeToPitch(ch->pitchInt));
}
//Just close the dam thing
sf_close(sf);
@@ -1573,6 +1666,27 @@ void SimpleSynth::updateVolume(int ch, int invol_ctrlval)
/*!
+ \fn SimpleSynth::updatePitch(int inpitch_ctrlval)
+ */
+void SimpleSynth::updatePitch(int ch, int inpitch_ctrlval)
+ {
+ SS_TRACE_IN
+ channels[ch].pitchInt = inpitch_ctrlval;
+ SS_TRACE_OUT
+ }
+
+/*!
+ \fn SimpleSynth::guiUpdatePitch(int ch, int bal)
+ */
+void SimpleSynth::guiUpdatePitch(int ch, int bal)
+ {
+ SS_TRACE_IN
+ MusECore::MidiPlayEvent ev(0, 0, ch, MusECore::ME_CONTROLLER, SS_CHANNEL_PITCH_CONTROLLER(ch), bal);
+ gui->writeEvent(ev);
+ SS_TRACE_OUT
+ }
+
+/*!
\fn SimpleSynth::guiUpdateBalance(int ch, int bal)
*/
void SimpleSynth::guiUpdateBalance(int ch, int bal)