summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
authorRobert Jonsson <spamatica@gmail.com>2013-04-04 19:10:10 +0000
committerRobert Jonsson <spamatica@gmail.com>2013-04-04 19:10:10 +0000
commitd930cf81c2cbcc65b373442a2aed3e631d331314 (patch)
tree84bbfaec2576086debd64d4d1f67e204ea6083cf /muse2
parent39fdcb8398390cae17bce642b358e74592676bf1 (diff)
simpledrums pitch and ctrl+arrows
Diffstat (limited to 'muse2')
-rw-r--r--muse2/muse/arranger/arranger.cpp2
-rw-r--r--muse2/muse/arranger/tlist.cpp11
-rw-r--r--muse2/muse/arranger/tlist.h1
-rw-r--r--muse2/synti/simpledrums2/common.h11
-rw-r--r--muse2/synti/simpledrums2/simpledrums.cpp252
-rw-r--r--muse2/synti/simpledrums2/simpledrums.h14
-rw-r--r--muse2/synti/simpledrums2/simpledrumsgui.cpp42
-rw-r--r--muse2/synti/simpledrums2/simpledrumsgui.h8
8 files changed, 262 insertions, 79 deletions
diff --git a/muse2/muse/arranger/arranger.cpp b/muse2/muse/arranger/arranger.cpp
index e5f22daf..89872bdf 100644
--- a/muse2/muse/arranger/arranger.cpp
+++ b/muse2/muse/arranger/arranger.cpp
@@ -513,6 +513,8 @@ Arranger::Arranger(ArrangerView* parent, const char* name)
connect(canvas, SIGNAL(horizontalScrollNoLimit(unsigned)),hscroll, SLOT(setPosNoLimit(unsigned)));
connect(time, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned)));
+ connect(list, SIGNAL(verticalScrollSetYpos(int)), vscroll, SLOT(setValue(int)));
+
connect(canvas, SIGNAL(tracklistChanged()), list, SLOT(tracklistChanged()));
connect(canvas, SIGNAL(dclickPart(MusECore::Track*)), SIGNAL(editPart(MusECore::Track*)));
connect(canvas, SIGNAL(startEditor(MusECore::PartList*,int)), SIGNAL(startEditor(MusECore::PartList*, int)));
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index dbed464e..5cea444d 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -1358,6 +1358,16 @@ void TList::moveSelection(int n)
(*s)->setSelected(false);
selTrack->setSelected(true);
+ // if selected track is outside of view, enforce scrolling
+ if (selTrack->y() > this->height()+ypos-20)
+ {
+ emit verticalScrollSetYpos(ypos+selTrack->height());
+ }
+ else if (selTrack->y() < ypos)
+ {
+ emit verticalScrollSetYpos(selTrack->y());
+ }
+
// rec enable track if expected
MusECore::TrackList recd = getRecEnabledTracks();
if (recd.size() == 1 && MusEGlobal::config.moveArmedCheckBox) { // one rec enabled track, move rec enabled with selection
@@ -2819,3 +2829,4 @@ void TList::setHeader(Header* h)
}
} // namespace MusEGui
+
diff --git a/muse2/muse/arranger/tlist.h b/muse2/muse/arranger/tlist.h
index fd05cac9..9201decd 100644
--- a/muse2/muse/arranger/tlist.h
+++ b/muse2/muse/arranger/tlist.h
@@ -135,6 +135,7 @@ class TList : public QWidget {
void selectionChanged(MusECore::Track*);
void keyPressExt(QKeyEvent*);
void redirectWheelEvent(QWheelEvent*);
+ void verticalScrollSetYpos(int ypos);
public slots:
void tracklistChanged();
diff --git a/muse2/synti/simpledrums2/common.h b/muse2/synti/simpledrums2/common.h
index e3046f0f..2651e90f 100644
--- a/muse2/synti/simpledrums2/common.h
+++ b/muse2/synti/simpledrums2/common.h
@@ -51,7 +51,8 @@
#define SS_DBG_LADSPA(string1) if (SS_DEBUG_LADSPA) fprintf(stderr, "%s:%d:%s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string1);
#define SS_DBG_LADSPA2(string1, string2) if (SS_DEBUG_LADSPA) fprintf(stderr, "%s:%d:%s: %s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string1, string2);
-#define SS_SYSEX_INIT_DATA_VERSION 1
+#define SS_SYSEX_INIT_DATA_VERSION 2
+// version 2 added pitching support
#define SS_SYSEX_EFFECT_INIT_DATA_VERSION 2 // Added Jun 15 2011. Original value was SS_SYSEX_INIT_DATA_VERSION (1). p4.0.27 Tim.
#define SS_NR_OF_CHANNELS 16
@@ -67,12 +68,13 @@
#define SS_CHANNEL_SENDFX2 5
#define SS_CHANNEL_SENDFX3 6
#define SS_CHANNEL_SENDFX4 7
+#define SS_CHANNEL_CTRL_PITCH 8
#define SS_PLUGIN_RETURN 0
#define SS_PLUGIN_ONOFF 1
#define SS_NR_OF_MASTER_CONTROLLERS 1
-#define SS_NR_OF_CHANNEL_CONTROLLERS 8
+#define SS_NR_OF_CHANNEL_CONTROLLERS 9
#define SS_NR_OF_PLUGIN_CONTROLLERS 2
#define SS_NR_OF_CONTROLLERS (SS_NR_OF_MASTER_CONTROLLERS + (SS_NR_OF_CHANNELS * SS_NR_OF_CHANNEL_CONTROLLERS) + (SS_NR_OF_PLUGIN_CONTROLLERS*SS_NR_OF_SENDEFFECTS))
@@ -87,6 +89,8 @@
#define SS_MASTER_CTRL_VOLUME SS_FIRST_MASTER_CONTROLLER
#define SS_CHANNEL_VOLUME_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_VOLUME)
+#define SS_CHANNEL_PITCH_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_PITCH)
+
#define SS_CHANNEL_PAN_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_PAN)
#define SS_CHANNEL_NOFF_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_NOFF)
#define SS_CHANNEL_ONOFF_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_ONOFF)
@@ -119,7 +123,8 @@ enum {
SS_SYSEX_SET_PLUGIN_PARAMETER_OK, // synth->gui: set plugin parameter (update gui)
SS_SYSEX_ERRORMSG, // synth -> gui: general error message from synth
SS_SYSEX_GET_INIT_DATA, // gui->synth: request init data
- SS_SYSEX_SEND_INIT_DATA // synth->gui: give gui init data
+ SS_SYSEX_SEND_INIT_DATA, // synth->gui: give gui init data
+ SS_SYSEX_PITCH_SAMPLE // gui->synth: set pitch and reload sample
};
extern int SS_samplerate;
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)
diff --git a/muse2/synti/simpledrums2/simpledrums.h b/muse2/synti/simpledrums2/simpledrums.h
index 5a7e2821..f4bf27ee 100644
--- a/muse2/synti/simpledrums2/simpledrums.h
+++ b/muse2/synti/simpledrums2/simpledrums.h
@@ -74,14 +74,15 @@ struct SS_SendFx
struct SS_Sample
{
+ SS_Sample() { data = 0; }
float* data;
int samplerate;
- int bits;
+ //int bits;
std::string filename;
long samples;
long frames;
int channels;
- SF_INFO sfinfo;
+ //SF_INFO sfinfo;
};
struct SS_Channel
@@ -89,6 +90,7 @@ struct SS_Channel
SS_ChannelState state;
const char* name;
SS_Sample* sample;
+ SS_Sample* originalSample;
int playoffset;
bool noteoff_ignore;
@@ -101,6 +103,7 @@ struct SS_Channel
int pan;
double balanceFactorL;
double balanceFactorR;
+ int pitchInt;
bool channel_on;
@@ -122,6 +125,9 @@ struct SS_SampleLoader
int ch_no;
};
+double rangeToPitch(int value);
+//int pitchToRange(double pitch);
+
class SimpleSynth : public Mess
{
public:
@@ -168,9 +174,11 @@ private:
bool loadSample(int ch_no, const char* filename);
void parseInitData(const unsigned char* data);
void updateVolume(int ch, int in_volume_ctrlval);
+ void updatePitch(int ch, int inpitch_ctrlval);
void updateBalance(int ch, int pan);
void guiNotifySampleCleared(int ch);
void guiUpdateBalance(int ch, int bal);
+ void guiUpdatePitch(int ch, int bal);
void guiUpdateVolume(int ch, int val);
void guiUpdateNoff(int ch, bool b);
void guiUpdateChoff(int ch, bool b);
@@ -182,6 +190,7 @@ private:
void cleanupPlugin(int id);
void setFxParameter(int fxid, int param, float val);
void clearSample(int ch);
+
double master_vol;
int master_vol_ctrlval;
@@ -192,6 +201,7 @@ private:
double* processBuffer[2];
};
+void resample(SS_Sample *origSmp, SS_Sample* newSample, double pitch);
static void* loadSampleThread(void*);
static pthread_mutex_t SS_LoaderMutex;
static SS_State synth_state;
diff --git a/muse2/synti/simpledrums2/simpledrumsgui.cpp b/muse2/synti/simpledrums2/simpledrumsgui.cpp
index c426d547..1b8acede 100644
--- a/muse2/synti/simpledrums2/simpledrumsgui.cpp
+++ b/muse2/synti/simpledrums2/simpledrumsgui.cpp
@@ -256,6 +256,7 @@ QChannelDial::QChannelDial(QWidget* parent, int ch, int fxid)
setTracking(true);
channel = ch;
sendfxid = fxid;
+ connect(this, SIGNAL(sliderReleased()), SLOT(forwardSliderMoved()));
}
/*!
@@ -276,6 +277,12 @@ void QChannelDial::sliderChange(SliderChange change)
emit valueChanged(channel, sendfxid, value());
}
+void QChannelDial::forwardSliderMoved()
+{
+ printf("forwardSliderMoved();\n");
+ emit sliderMoved(channel, value());
+}
+
/*!
\fn SimpleSynthGui::SimpleSynthGui()
*/
@@ -338,6 +345,15 @@ SimpleSynthGui::SimpleSynthGui()
inchnlLayout->addWidget(volumeSliders[i]);
connect(volumeSliders[i], SIGNAL(valueChanged(int, int)), SLOT(volumeChanged(int, int)));
+ pitchKnobs[i] = new QChannelDial(channelButtonGroups[i], i, 0);
+ pitchKnobs[i]->setRange(-63,63);
+ pitchKnobs[i]->setValue(0);
+ pitchKnobs[i]->setToolTip("Pitch, channel " + QString::number(i + 1));
+ pitchKnobs[i]->setFixedSize(30,30);
+ inchnlLayout->addWidget(pitchKnobs[i]);
+ connect(pitchKnobs[i], SIGNAL(sliderMoved(int,int)), SLOT(pitchChanged(int,int)));
+
+
nOffLabel[i] = new QLabel(channelButtonGroups[i]);
// nOffLabel[i]->setMinimumSize(SS_NONOFF_LABEL_WIDTH, SS_NONOFF_LABEL_HEIGHT);
nOffLabel[i]->setText("nOff");
@@ -544,12 +560,14 @@ void SimpleSynthGui::processEvent(const MusECore::MidiPlayEvent& ev)
switch(id) {
case SS_CHANNEL_CTRL_VOLUME:
volumeSliders[ch]->blockSignals(true);
-
- ///volumeSliders[ch]->setValue(SS_VOLUME_MAX_VALUE - val);
- volumeSliders[ch]->setValue(val); // p4.0.27
-
+ volumeSliders[ch]->setValue(val);
volumeSliders[ch]->blockSignals(false);
break;
+ case SS_CHANNEL_CTRL_PITCH:
+ pitchKnobs[ch]->blockSignals(true);
+ pitchKnobs[ch]->setValue(-(val-63));
+ pitchKnobs[ch]->blockSignals(false);
+ break;
case SS_CHANNEL_CTRL_PAN:
panSliders[ch]->blockSignals(true);
@@ -767,6 +785,15 @@ void SimpleSynthGui::volumeChanged(int channel, int val)
}
/*!
+ \fn SimpleSynthGui::pitchChanged(int val)
+ */
+void SimpleSynthGui::pitchChanged(int channel, int val)
+ {
+ printf("Gui::pitchChanged %d %d\n", channel, val);
+ setChannelPitch(channel, -val+63);
+ }
+
+/*!
\fn SimpleSynthGui::panChanged(int channel, int value)
*/
void SimpleSynthGui::panChanged(int channel, int value)
@@ -815,6 +842,13 @@ void SimpleSynthGui::setChannelVolume(int channel, int volume)
sendController(0, SS_CHANNEL_VOLUME_CONTROLLER(channel), (int)volume);
}
+/*!
+ \fn SimpleSynthGui::setChannelPitch(int channel, byte pitch)
+ */
+void SimpleSynthGui::setChannelPitch(int channel, int pitch)
+ {
+ sendController(0, SS_CHANNEL_PITCH_CONTROLLER(channel), (int)pitch);
+ }
/*!
\fn SimpleSynthGui::loadSampleDialogue(int channel)
diff --git a/muse2/synti/simpledrums2/simpledrumsgui.h b/muse2/synti/simpledrums2/simpledrumsgui.h
index 05c38cfd..79266dd1 100644
--- a/muse2/synti/simpledrums2/simpledrumsgui.h
+++ b/muse2/synti/simpledrums2/simpledrumsgui.h
@@ -154,6 +154,7 @@ class QChannelDial : public QDial
signals:
void valueChanged(int channel, int fxid, int val);
+ void sliderMoved(int channel, int val);
///public slots:
/// virtual void setValue(int val);
@@ -161,7 +162,9 @@ class QChannelDial : public QDial
protected:
int channel;
int sendfxid;
- virtual void sliderChange(SliderChange change);
+ virtual void sliderChange(SliderChange change);
+ private slots:
+ void forwardSliderMoved();
};
//--------------------------------------
@@ -174,6 +177,7 @@ class SimpleSynthGui : public QDialog, public Ui::SimpleDrumsGuiBase, public Mes
// MESS interface:
virtual void processEvent(const MusECore::MidiPlayEvent& ev);
void setChannelVolume(int channel, int volume);
+ void setChannelPitch(int channel, int volume);
void displayPluginGui();
QGroupBox* channelButtonGroups[SS_NR_OF_CHANNELS];
QGroupBox* masterButtonGroup;
@@ -181,6 +185,7 @@ class SimpleSynthGui : public QDialog, public Ui::SimpleDrumsGuiBase, public Mes
///QInvertedChannelSlider* volumeSliders[SS_NR_OF_CHANNELS];
QChannelSlider* volumeSliders[SS_NR_OF_CHANNELS]; // p4.0.27 Tim. Inverted not correct. Was WIP?
+ QChannelDial* pitchKnobs[SS_NR_OF_CHANNELS];
QChannelSlider* panSliders[SS_NR_OF_CHANNELS];
QChannelCheckbox* onOff[SS_NR_OF_CHANNELS];
@@ -219,6 +224,7 @@ class SimpleSynthGui : public QDialog, public Ui::SimpleDrumsGuiBase, public Mes
private slots:
void volumeChanged(int channel, int val);
+ void pitchChanged(int channel, int val);
void panChanged(int channel, int value);
void channelOnOff(int channel, bool state);
void channelNoteOffIgnore(int channel, bool state);