diff options
-rw-r--r-- | muse2/muse/arranger/arranger.cpp | 2 | ||||
-rw-r--r-- | muse2/muse/arranger/tlist.cpp | 11 | ||||
-rw-r--r-- | muse2/muse/arranger/tlist.h | 1 | ||||
-rw-r--r-- | muse2/synti/simpledrums2/common.h | 11 | ||||
-rw-r--r-- | muse2/synti/simpledrums2/simpledrums.cpp | 252 | ||||
-rw-r--r-- | muse2/synti/simpledrums2/simpledrums.h | 14 | ||||
-rw-r--r-- | muse2/synti/simpledrums2/simpledrumsgui.cpp | 42 | ||||
-rw-r--r-- | muse2/synti/simpledrums2/simpledrumsgui.h | 8 |
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); |