diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp index 4624184b..792f36c9 100644 --- a/src/tracker/SampleEditor.cpp +++ b/src/tracker/SampleEditor.cpp @@ -3033,12 +3033,12 @@ void SampleEditor::tool_generateHalfSine(const FilterParameters* par) const float amplify = par->getParameter(0).floatPart; // generate half sine wave here - for (i = sStart; i < sEnd / 2; i++) + for (i = sStart; i < sStart + sLen / 2; i++) { float per = (i - sStart) / (float)sLen * numPeriods; setFloatSampleInWaveform(i, (float)sin(per) * amplify); } - for (i = sEnd / 2; i < sEnd; i++) + for (; i < sEnd; i++) { setFloatSampleInWaveform(i, 0); } @@ -3083,17 +3083,72 @@ void SampleEditor::tool_generateAbsoluteSine(const FilterParameters* par) const float numPeriods = (float)(6.283185307179586476925286766559 * par->getParameter(1).floatPart); const float amplify = par->getParameter(0).floatPart; - // generate half sine wave in first and second halves - for (i = sStart; i < sEnd / 2; i++) + // generate absolute sine wave here + for (i = sStart; i < sEnd; i++) + { + float per = (i - sStart) / (float)sLen * numPeriods; + setFloatSampleInWaveform(i, fabs((float)sin(per) * amplify)); + } + + finishUndo(); + + postFilter(); +} + +void SampleEditor::tool_generateQuarterSine(const FilterParameters* par) +{ + if (isEmptySample()) + return; + + pp_int32 sStart = selectionStart; + pp_int32 sEnd = selectionEnd; + + if (hasValidSelection()) + { + if (sStart >= 0 && sEnd >= 0) + { + if (sEnd < sStart) + { + pp_int32 s = sEnd; sEnd = sStart; sStart = s; + } + } + } + else + { + sStart = 0; + sEnd = sample->samplen; + } + + preFilter(&SampleEditor::tool_generateQuarterSine, par); + + mp_sint32 sLen = sEnd - sStart; + + prepareUndo(); + + pp_int32 i; + + const float numPeriods = (float)(6.283185307179586476925286766559 * par->getParameter(1).floatPart); + const float amplify = par->getParameter(0).floatPart; + + // generate quarter sine wave in first and third quarters + for (i = sStart; i < sStart + sLen / 4; i++) { float per = (i - sStart) / (float)sLen * numPeriods; setFloatSampleInWaveform(i, (float)sin(per) * amplify); } - for (i = sEnd / 2; i < sEnd; i++) + for (; i < sStart + sLen / 2; i++) { - float per = (i - sEnd / 2) / (float)sLen * numPeriods; + setFloatSampleInWaveform(i, 0); + } + for (; i < sStart + sLen * 3 / 4; i++) + { + float per = (i - (sStart + sLen / 2)) / (float)sLen * numPeriods; setFloatSampleInWaveform(i, (float)sin(per) * amplify); } + for (; i < sEnd; i++) + { + setFloatSampleInWaveform(i, 0); + } finishUndo(); diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h index a516c967..8757eeff 100644 --- a/src/tracker/SampleEditor.h +++ b/src/tracker/SampleEditor.h @@ -357,6 +357,7 @@ class SampleEditor : public EditorBase void tool_generateSawtooth(const FilterParameters* par); void tool_generateHalfSine(const FilterParameters* par); void tool_generateAbsoluteSine(const FilterParameters* par); + void tool_generateQuarterSine(const FilterParameters* par); void tool_applyLastFilter(); bool tool_canApplyLastFilter() const; diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp index de6d8bae..a6b6e407 100644 --- a/src/tracker/SampleEditorControl.cpp +++ b/src/tracker/SampleEditorControl.cpp @@ -162,6 +162,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id, subMenuGenerators->addEntry("Sawtooth" PPSTR_PERIODS, MenuCommandIDGenerateSawtooth); subMenuGenerators->addEntry("Half Sine" PPSTR_PERIODS, MenuCommandIDGenerateHalfSine); subMenuGenerators->addEntry("Absolute Sine" PPSTR_PERIODS, MenuCommandIDGenerateAbsoluteSine); + subMenuGenerators->addEntry("Quarter Sine" PPSTR_PERIODS, MenuCommandIDGenerateQuarterSine); subMenuGenerators->addEntry("Silence" PPSTR_PERIODS, MenuCommandIDGenerateSilence); // build context menu @@ -1717,6 +1718,7 @@ void SampleEditorControl::invokeContextMenu(const PPPoint& p, bool translatePoin subMenuGenerators->setState(MenuCommandIDGenerateSawtooth, isEmptySample); subMenuGenerators->setState(MenuCommandIDGenerateHalfSine, isEmptySample); subMenuGenerators->setState(MenuCommandIDGenerateAbsoluteSine, isEmptySample); + subMenuGenerators->setState(MenuCommandIDGenerateQuarterSine, isEmptySample); subMenuGenerators->setState(MenuCommandIDGenerateSilence, isEmptySample); parentScreen->setContextMenuControl(editMenuControl); @@ -1907,6 +1909,10 @@ void SampleEditorControl::executeMenuCommand(pp_int32 commandId) invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateAbsoluteSine); break; + case MenuCommandIDGenerateQuarterSine: + invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateQuarterSine); + break; + } } diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h index 570aabcc..9f9bd0bf 100644 --- a/src/tracker/SampleEditorControl.h +++ b/src/tracker/SampleEditorControl.h @@ -309,7 +309,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub MenuCommandIDGenerateTriangle, MenuCommandIDGenerateSawtooth, MenuCommandIDGenerateHalfSine, - MenuCommandIDGenerateAbsoluteSine + MenuCommandIDGenerateAbsoluteSine, + MenuCommandIDGenerateQuarterSine }; void executeMenuCommand(pp_int32 commandId); @@ -355,7 +356,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub SampleToolTypeGenerateTriangle, SampleToolTypeGenerateSawtooth, SampleToolTypeGenerateHalfSine, - SampleToolTypeGenerateAbsoluteSine + SampleToolTypeGenerateAbsoluteSine, + SampleToolTypeGenerateQuarterSine }; private: diff --git a/src/tracker/SampleEditorControlToolHandler.cpp b/src/tracker/SampleEditorControlToolHandler.cpp index 675d0b55..62292600 100644 --- a/src/tracker/SampleEditorControlToolHandler.cpp +++ b/src/tracker/SampleEditorControlToolHandler.cpp @@ -155,6 +155,7 @@ bool SampleEditorControl::invokeToolParameterDialog(SampleEditorControl::ToolHan case ToolHandlerResponder::SampleToolTypeGenerateSawtooth: case ToolHandlerResponder::SampleToolTypeGenerateHalfSine: case ToolHandlerResponder::SampleToolTypeGenerateAbsoluteSine: + case ToolHandlerResponder::SampleToolTypeGenerateQuarterSine: { dialog = new DialogWithValues(parentScreen, toolHandlerResponder, PP_DEFAULT_ID, "Generate waveform" PPSTR_PERIODS, DialogWithValues::ValueStyleEnterTwoValues); static_cast(dialog)->setValueOneCaption("Volume in percent:"); @@ -358,6 +359,17 @@ bool SampleEditorControl::invokeTool(ToolHandlerResponder::SampleToolTypes type) break; } + case ToolHandlerResponder::SampleToolTypeGenerateQuarterSine: + { + lastValues.waveFormVolume = static_cast(dialog)->getValueOne(); + lastValues.waveFormNumPeriods = static_cast(dialog)->getValueTwo(); + FilterParameters par(2); + par.setParameter(0, FilterParameters::Parameter(lastValues.waveFormVolume / 100.0f)); + par.setParameter(1, FilterParameters::Parameter(lastValues.waveFormNumPeriods)); + sampleEditor->tool_generateQuarterSine(&par); + break; + } + default: break; }