diff --git a/sources/Application/Instruments/SampleInstrument.cpp b/sources/Application/Instruments/SampleInstrument.cpp index f7c4240d6..85d757616 100644 --- a/sources/Application/Instruments/SampleInstrument.cpp +++ b/sources/Application/Instruments/SampleInstrument.cpp @@ -37,7 +37,6 @@ SampleInstrument::SampleInstrument() crush_(FourCC::SampleInstrumentCrush, 16), drive_(FourCC::SampleInstrumentCrushVolume, 0xFF), downsample_(FourCC::SampleInstrumentDownsample, 0), - slices_(FourCC::SampleInstrumentSlices, -1), rootNote_(FourCC::SampleInstrumentRootNote, 60), fineTune_(FourCC::SampleInstrumentFineTune, 0x7F), pan_(FourCC::SampleInstrumentPan, 0x7F), @@ -72,7 +71,6 @@ SampleInstrument::SampleInstrument() variables_.insert(variables_.end(), &crush_); variables_.insert(variables_.end(), &drive_); variables_.insert(variables_.end(), &downsample_); - variables_.insert(variables_.end(), &slices_); variables_.insert(variables_.end(), &rootNote_); variables_.insert(variables_.end(), &fineTune_); variables_.insert(variables_.end(), &pan_); @@ -149,96 +147,9 @@ bool SampleInstrument::Start(int channel, unsigned char midinote, rp->pan_ = rp->basePan_ = i2fp(pan_.GetInt()); - // TODO (democloid): We have 3 potential differnt modes, single sample - // multisample based on source file (CUEs not currently supported) which would - // be evaluated on the source material and use the IsMulti call on the source - // Explicit slicing, we tell how we want the sample file to be interpreted - int32_t slicedStart = 0; if (!source_->IsMulti()) { - // Check if slices are disabled or set to an invalid value - // -1, 0, or 1 all mean no slices - if (slices_.GetInt() <= 1) { - // single sample mode (no slices) - rp->rendLoopStart_ = loopStart_.GetInt(); - rp->rendLoopEnd_ = loopEnd_.GetInt(); - - // If end is 0 or negative, use the full sample size - if (rp->rendLoopEnd_ <= 0) { - rp->rendLoopEnd_ = GetSampleSize(channel); - } - } else { - // sliced mode - uint32_t totalSize = GetSampleSize(channel); - uint8_t numSlices = (uint8_t)slices_.GetInt(); - - // Get user-defined start and end points - uint32_t userStart = start_.GetInt(); - uint32_t userEnd = loopEnd_.GetInt(); - - // Ensure we have enough range for the number of slices - // End point should be at least (numSlices) more than start point - if (userEnd <= userStart + numSlices) { - // just dont play anything in this case - return false; - } - - // Calculate the effective sample range to slice - uint32_t effectiveStart = userStart; - uint32_t effectiveEnd = userEnd; - uint32_t effectiveSize = effectiveEnd - effectiveStart; - - // Ensure we have a valid size - if (effectiveSize <= 0) { - return false; - } - - // Ensure at least 1 sample per slice - uint32_t sliceSize = effectiveSize / numSlices; - if (sliceSize <= 0) { - return false; - } - - int note = rp->midiNote_; - int rootNoteVal = rootNote_.GetInt(); - int8_t sliceNum = note - rootNoteVal; - Trace::Debug("SLICES: Midi note %i Root %i Slice Number: %i", note, - rootNoteVal, sliceNum); - - if ((sliceNum < 0) || (sliceNum >= numSlices)) { - Trace::Debug("SLICES: Out of range, discarded"); - return false; - } - - // Calculate slice boundaries within the effective range - uint32_t sliceStart = effectiveStart + (sliceNum * sliceSize); - uint32_t sliceEnd = sliceStart + sliceSize; - - // Ensure slice boundaries are within sample bounds - if (sliceEnd > totalSize) { - sliceEnd = totalSize; - } - - // Set playback points for this slice - slicedStart = sliceStart; - - // Make sure start point doesn't exceed sample end - if (sliceStart >= effectiveEnd) { - Trace::Debug("SLICES: Start point exceeds sample end"); - return false; - } - - // For slices, we always use one-shot mode regardless of the loop mode - // setting This overrides any loop mode setting when using slices - loopMode_.SetInt(SILM_ONESHOT); - Trace::Debug("SLICES: Enforcing one-shot mode for slices"); - - // Set the boundaries for one-shot playback of this slice - rp->rendLoopStart_ = sliceStart; - rp->rendLoopEnd_ = sliceEnd; - - Trace::Debug("SLICES: Slice %i boundaries: %i to %i (one-shot mode)", - sliceNum, sliceStart, sliceEnd); - } + rp->rendLoopStart_ = loopStart_.GetInt(); + rp->rendLoopEnd_ = loopEnd_.GetInt(); } else { long start = source_->GetLoopStart(rp->midiNote_); if (start > 0) { @@ -274,20 +185,8 @@ bool SampleInstrument::Start(int channel, unsigned char midinote, // if instrument sampled below 44.1Khz, should // travel slower in sample - // Set the initial playback position to the slice start - rp->rendFirst_ = slicedStart; + rp->rendFirst_ = start_.GetInt(); rp->position_ = float(rp->rendFirst_); - - // Ensure position stays within valid boundaries - if (rp->position_ < 0) { - rp->position_ = 0; - } - - // For non-oneshot modes, ensure we start at loop start if needed - if (loopMode_.GetInt() != SILM_ONESHOT && - rp->position_ < float(rp->rendLoopStart_)) { - rp->position_ = float(rp->rendLoopStart_); - } rp->baseSpeed_ = fl2fp(source_->GetSampleRate(rp->midiNote_) / driverRate); rp->reverse_ = (rp->rendLoopEnd_ < rp->position_); @@ -874,25 +773,8 @@ bool SampleInstrument::Render(int channel, fixed *buffer, int size, rp->reverse_ = rpReverse; // Update final sample position - if (input && wavbuf) { - rp->position_ = - (((char *)input) - wavbuf) / (2 * channelCount) + fp2fl(fpPos); - - // Safety check for valid position - if (rp->position_ < 0) { - rp->position_ = 0; - } - - // Ensure position stays within slice boundaries for sliced mode - if (slices_.GetInt() > 0 && !source_->IsMulti()) { - // If we've gone past the slice end, reset to loop start for looping - // modes - if (loopMode_.GetInt() != SILM_ONESHOT && - rp->position_ >= float(rp->rendLoopEnd_)) { - rp->position_ = float(rp->rendLoopStart_); - } - } - } + rp->position_ = + (((char *)input) - wavbuf) / (2 * channelCount) + fp2fl(fpPos); somethingToMix = true; } @@ -1324,4 +1206,4 @@ bool SampleInstrument::IsMulti() { return source_->IsMulti(); } void SampleInstrument::EnableDownsamplingLegacy() { useDirtyDownsampling_ = true; Trace::Log("CONFIG", "Enabling downsampling legacy"); -} +} \ No newline at end of file diff --git a/sources/Application/Instruments/SampleInstrument.h b/sources/Application/Instruments/SampleInstrument.h index 8f5d3e011..f1c1dcba1 100644 --- a/sources/Application/Instruments/SampleInstrument.h +++ b/sources/Application/Instruments/SampleInstrument.h @@ -72,7 +72,7 @@ class SampleInstrument : public I_Instrument, I_Observer { void doKRateUpdate(int channel); private: - etl::list variables_; + etl::list variables_; SoundSource *source_; static struct renderParams renderParams_[SONG_CHANNEL_COUNT]; @@ -88,7 +88,6 @@ class SampleInstrument : public I_Instrument, I_Observer { Variable crush_; Variable drive_; Variable downsample_; - Variable slices_; Variable rootNote_; Variable fineTune_; Variable pan_; diff --git a/sources/Application/Instruments/WavFile.cpp b/sources/Application/Instruments/WavFile.cpp index 63e231eeb..3e2829677 100644 --- a/sources/Application/Instruments/WavFile.cpp +++ b/sources/Application/Instruments/WavFile.cpp @@ -329,4 +329,4 @@ void WavFile::Close() { readBufferSize_ = 0; }; -int WavFile::GetRootNote(int note) { return 60; } +int WavFile::GetRootNote(int note) { return 60; } \ No newline at end of file diff --git a/sources/Application/Instruments/WavFile.h b/sources/Application/Instruments/WavFile.h index 784df6910..3542dac7e 100644 --- a/sources/Application/Instruments/WavFile.h +++ b/sources/Application/Instruments/WavFile.h @@ -50,4 +50,4 @@ class WavFile : public SoundSource { static bool initChunkSize_; static unsigned char readBuffer_[BUFFER_SIZE]; }; -#endif +#endif \ No newline at end of file diff --git a/sources/Application/Views/InstrumentView.cpp b/sources/Application/Views/InstrumentView.cpp index 28ba2f23e..5b6609dfc 100644 --- a/sources/Application/Views/InstrumentView.cpp +++ b/sources/Application/Views/InstrumentView.cpp @@ -141,7 +141,7 @@ void InstrumentView::onInstrumentChange() { refreshInstrumentFields(); }; -void InstrumentView::refreshInstrumentFields(FourCC focus) { +void InstrumentView::refreshInstrumentFields() { for (auto &f : intVarField_) { f.RemoveObserver(*this); } @@ -167,7 +167,7 @@ void InstrumentView::refreshInstrumentFields(FourCC focus) { // first put back the type field as its shown on *all* instrument types fieldList_.insert(fieldList_.end(), &(*typeIntVarField_.rbegin())); - lastFocusID_ = focus; + lastFocusID_ = FourCC::VarInstrumentType; // Re-add the action fields for export and import only if not IT_NONE if (instrumentType_.GetInt() != IT_NONE) { @@ -269,15 +269,6 @@ void InstrumentView::fillSampleParameters() { intVarField_.emplace_back(position, *v, "pan: %2.2X", 0, 0xFE, 1, 0x10); fieldList_.insert(fieldList_.end(), &(*intVarField_.rbegin())); - position._x += 10; - Variable *s = instrument->FindVariable(FourCC::SampleInstrumentSlices); - intVarOffField_.emplace_back(position, *s, "Slices: %d", 2, 64, 1, 8); - fieldList_.insert(fieldList_.end(), &(*intVarOffField_.rbegin())); - - // add observer - (*intVarOffField_.rbegin()).AddObserver(*this); - - position._x -= 10; position._y += 1; v = instrument->FindVariable(FourCC::SampleInstrumentRootNote); noteVarField_.emplace_back(position, *v, "root note: %s", 0, 0x7F, 1, 0x0C); @@ -342,39 +333,20 @@ void InstrumentView::fillSampleParameters() { position._y += 1; v = instrument->FindVariable(FourCC::SampleInstrumentStart); - // Calculate max value for start field - use full sample size if no slices - int maxStartValue = instrument->GetSampleSize() - 1; - if (s->GetInt() > 0) { - // If slices are enabled, we still allow editing the full range - // The actual slice boundaries will be enforced during playback - } bigHexVarField_.emplace_back(position, *v, 7, "start: %7.7X", 0, - maxStartValue, 16); + instrument->GetSampleSize() - 1, 16); fieldList_.insert(fieldList_.end(), &(*bigHexVarField_.rbegin())); position._y += 1; v = instrument->FindVariable(FourCC::SampleInstrumentLoopStart); - // Calculate max value for loop start field - use full sample size if no - // slices - int maxLoopStartValue = instrument->GetSampleSize() - 1; - if (s->GetInt() > 0) { - // If slices are enabled, we still allow editing the full range - // The actual slice boundaries will be enforced during playback - } bigHexVarField_.emplace_back(position, *v, 7, "loop start: %7.7X", 0, - maxLoopStartValue, 16); + instrument->GetSampleSize() - 1, 16); fieldList_.insert(fieldList_.end(), &(*bigHexVarField_.rbegin())); position._y += 1; v = instrument->FindVariable(FourCC::SampleInstrumentEnd); - // Calculate max value for loop end field - use full sample size if no slices - int maxLoopEndValue = instrument->GetSampleSize() - 1; - if (s->GetInt() > 0) { - // If slices are enabled, we still allow editing the full range - // The actual slice boundaries will be enforced during playback - } bigHexVarField_.emplace_back(position, *v, 7, "loop end: %7.7X", 0, - maxLoopEndValue, 16); + instrument->GetSampleSize() - 1, 16); fieldList_.insert(fieldList_.end(), &(*bigHexVarField_.rbegin())); v = instrument->FindVariable(FourCC::SampleInstrumentTableAutomation); @@ -988,22 +960,6 @@ void InstrumentView::Update(Observable &o, I_ObservableData *data) { SetChanged(); NotifyObservers(&ve); } break; - case FourCC::SampleInstrumentSlices: { - // We are assuming we can only get here when instrument is Sample, safe? - Trace::Debug("INSTRUMENTVIEW", "slice changed, redraw!"); - I_Instrument *instrument = getInstrument(); - // In slice change, reset markers for start and loop start - Variable *ls = instrument->FindVariable(FourCC::SampleInstrumentStart); - ls->SetInt(0, true); - ls = instrument->FindVariable(FourCC::SampleInstrumentLoopStart); - ls->SetInt(0, true); - Variable *slices = instrument->FindVariable(FourCC::SampleInstrumentSlices); - ls = instrument->FindVariable(FourCC::SampleInstrumentEnd); - ls->SetInt((((SampleInstrument *)instrument)->GetSampleSize() - 1) / - slices->GetInt(), - true); - refreshInstrumentFields(FourCC::SampleInstrumentSlices); - } break; case FourCC::MidiInstrumentProgram: { // When program value changes, send a MIDI Program Change message I_Instrument *instr = getInstrument(); @@ -1140,12 +1096,3 @@ void InstrumentView::handleInstrumentExport() { } } } - -// Redraw all UI fields to reflect updated variable values -void InstrumentView::redrawAllFields() { - for (auto field : fieldList_) { - if (field) { - field->Draw(w_); - } - } -} diff --git a/sources/Application/Views/InstrumentView.h b/sources/Application/Views/InstrumentView.h index f5379f3fe..57b6656cb 100644 --- a/sources/Application/Views/InstrumentView.h +++ b/sources/Application/Views/InstrumentView.h @@ -41,13 +41,11 @@ class InstrumentView : public FieldView, public I_Observer { void fillNoneParameters(); I_Instrument *getInstrument(); void Update(Observable &o, I_ObservableData *d); - void refreshInstrumentFields(FourCC focus = FourCC::VarInstrumentType); + void refreshInstrumentFields(); void addNameTextField(I_Instrument *instr, GUIPoint &position); void handleInstrumentExport(); private: - // Redraw all fields to reflect updated variable values - void redrawAllFields(); Project *project_; FourCC lastFocusID_; WatchedVariable instrumentType_; @@ -58,11 +56,11 @@ class InstrumentView : public FieldView, public I_Observer { etl::vector typeIntVarField_; etl::vector actionField_; - etl::vector intVarField_; + etl::vector intVarField_; etl::vector noteVarField_; etl::vector staticField_; etl::vector bigHexVarField_; - etl::vector intVarOffField_; + etl::vector intVarOffField_; etl::vector bitmaskVarField_; etl::vector, 1> nameTextField_; etl::vector nameVariables_; diff --git a/sources/Foundation/Types/Types.h b/sources/Foundation/Types/Types.h index bb90327f4..37504dd0b 100644 --- a/sources/Foundation/Types/Types.h +++ b/sources/Foundation/Types/Types.h @@ -296,7 +296,6 @@ struct FourCC { ETL_ENUM_TYPE(SampleInstrumentEnd, "end") ETL_ENUM_TYPE(SampleInstrumentTable, "table") ETL_ENUM_TYPE(SampleInstrumentTableAutomation, "table automation") - ETL_ENUM_TYPE(SampleInstrumentSlices, "Slices") ETL_ENUM_TYPE(MidiInstrumentChannel, "channel") ETL_ENUM_TYPE(InstrumentName, "name") ETL_ENUM_TYPE(MidiInstrumentName, "midi name")