123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901 |
- /*
- * SampleEditorDialogs.cpp
- * -----------------------
- * Purpose: Code for various dialogs that are used in the sample editor.
- * Notes : (currently none)
- * Authors: Olivier Lapicque
- * OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #include "stdafx.h"
- #include "resource.h"
- #include "Reporting.h"
- #include "MPTrackUtil.h"
- #include "Mptrack.h"
- #include "../common/misc_util.h"
- #include "../soundlib/Snd_defs.h"
- #include "../soundlib/ModSample.h"
- #include "SampleEditorDialogs.h"
- #include "ProgressDialog.h"
- OPENMPT_NAMESPACE_BEGIN
- //////////////////////////////////////////////////////////////////////////
- // Sample amplification dialog
- BEGIN_MESSAGE_MAP(CAmpDlg, CDialog)
- ON_WM_DESTROY()
- ON_EN_CHANGE(IDC_EDIT2, &CAmpDlg::EnableFadeIn)
- ON_EN_CHANGE(IDC_EDIT3, &CAmpDlg::EnableFadeOut)
- END_MESSAGE_MAP()
- void CAmpDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAmpDlg)
- DDX_Control(pDX, IDC_COMBO1, m_fadeBox);
- //}}AFX_DATA_MAP
- }
- CAmpDlg::CAmpDlg(CWnd *parent, AmpSettings &settings, int16 factorMin, int16 factorMax)
- : CDialog(IDD_SAMPLE_AMPLIFY, parent)
- , m_settings(settings)
- , m_nFactorMin(factorMin)
- , m_nFactorMax(factorMax)
- {}
- BOOL CAmpDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- CSpinButtonCtrl *spin = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN1);
- spin->SetRange32(m_nFactorMin, m_nFactorMax);
- spin->SetPos32(m_settings.factor);
- spin = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN2);
- spin->SetRange32(0, 100);
- spin->SetPos32(m_settings.fadeInStart);
- spin = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN3);
- spin->SetRange32(0, 100);
- spin->SetPos32(m_settings.fadeOutEnd);
- SetDlgItemInt(IDC_EDIT1, m_settings.factor);
- SetDlgItemInt(IDC_EDIT2, m_settings.fadeInStart);
- SetDlgItemInt(IDC_EDIT3, m_settings.fadeOutEnd);
- m_edit.SubclassDlgItem(IDC_EDIT1, this);
- m_edit.AllowFractions(false);
- m_edit.AllowNegative(m_nFactorMin < 0);
- m_editFadeIn.SubclassDlgItem(IDC_EDIT2, this);
- m_editFadeIn.AllowFractions(false);
- m_editFadeIn.AllowNegative(m_nFactorMin < 0);
- m_editFadeOut.SubclassDlgItem(IDC_EDIT3, this);
- m_editFadeOut.AllowFractions(false);
- m_editFadeOut.AllowNegative(m_nFactorMin < 0);
- const struct
- {
- const TCHAR *name;
- Fade::Law id;
- } fadeLaws[] =
- {
- { _T("Linear"), Fade::kLinear },
- { _T("Exponential"), Fade::kPow },
- { _T("Square Root"), Fade::kSqrt },
- { _T("Logarithmic"), Fade::kLog },
- { _T("Quarter Sine"), Fade::kQuarterSine },
- { _T("Half Sine"), Fade::kHalfSine },
- };
- // Create icons for fade laws
- const int cx = Util::ScalePixels(16, m_hWnd);
- const int cy = Util::ScalePixels(16, m_hWnd);
- const int imgWidth = cx * static_cast<int>(std::size(fadeLaws));
- m_list.Create(cx, cy, ILC_COLOR32 | ILC_MASK, 0, 1);
- std::vector<COLORREF> bits(imgWidth * cy, RGB(255, 0, 255));
- const COLORREF col = GetSysColor(COLOR_WINDOWTEXT);
- for(int i = 0, baseX = 0; i < static_cast<int>(std::size(fadeLaws)); i++, baseX += cx)
- {
- Fade::Func fadeFunc = Fade::GetFadeFunc(fadeLaws[i].id);
- int oldVal = cy - 1;
- for(int x = 0; x < cx; x++)
- {
- int val = cy - 1 - mpt::saturate_round<int>(cy * fadeFunc(static_cast<double>(x) / cx));
- Limit(val, 0, cy - 1);
- if(oldVal > val && x > 0)
- {
- int dy = (oldVal - val) / 2;
- for(int y = oldVal * imgWidth; dy != 0; y -= imgWidth, dy--)
- {
- bits[baseX + (x - 1) + y] = col;
- }
- oldVal -= dy + 1;
- }
- for(int y = oldVal * imgWidth; y >= val * imgWidth; y -= imgWidth)
- {
- bits[baseX + x + y] = col;
- }
- oldVal = val;
- }
- }
- CBitmap bitmap;
- bitmap.CreateBitmap(cx * static_cast<int>(std::size(fadeLaws)), cy, 1, 32, bits.data());
- m_list.Add(&bitmap, RGB(255, 0, 255));
- bitmap.DeleteObject();
- m_fadeBox.SetImageList(&m_list);
- // Add fade laws to list
- COMBOBOXEXITEM cbi;
- MemsetZero(cbi);
- cbi.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM;
- for(int i = 0; i < static_cast<int>(std::size(fadeLaws)); i++)
- {
- cbi.iItem = i;
- cbi.pszText = const_cast<LPTSTR>(fadeLaws[i].name);
- cbi.iImage = cbi.iSelectedImage = i;
- cbi.lParam = fadeLaws[i].id;
- m_fadeBox.InsertItem(&cbi);
- if(fadeLaws[i].id == m_settings.fadeLaw) m_fadeBox.SetCurSel(i);
- }
- m_locked = false;
- return TRUE;
- }
- void CAmpDlg::OnDestroy()
- {
- m_list.DeleteImageList();
- }
- void CAmpDlg::OnOK()
- {
- m_settings.factor = static_cast<int16>(Clamp(static_cast<int>(GetDlgItemInt(IDC_EDIT1)), m_nFactorMin, m_nFactorMax));
- m_settings.fadeInStart = Clamp(static_cast<int>(GetDlgItemInt(IDC_EDIT2)), m_nFactorMin, m_nFactorMax);
- m_settings.fadeOutEnd = Clamp(static_cast<int>(GetDlgItemInt(IDC_EDIT3)), m_nFactorMin, m_nFactorMax);
- m_settings.fadeIn = (IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED);
- m_settings.fadeOut = (IsDlgButtonChecked(IDC_CHECK2) != BST_UNCHECKED);
- m_settings.fadeLaw = static_cast<Fade::Law>(m_fadeBox.GetItemData(m_fadeBox.GetCurSel()));
- CDialog::OnOK();
- }
- //////////////////////////////////////////////////////////////
- // Sample import dialog
- SampleIO CRawSampleDlg::m_format(SampleIO::_8bit, SampleIO::mono, SampleIO::littleEndian, SampleIO::signedPCM);
- SmpLength CRawSampleDlg::m_offset = 0;
- BEGIN_MESSAGE_MAP(CRawSampleDlg, CDialog)
- ON_COMMAND_RANGE(IDC_RADIO1, IDC_RADIO4, &CRawSampleDlg::OnBitDepthChanged)
- ON_COMMAND_RANGE(IDC_RADIO7, IDC_RADIO10, &CRawSampleDlg::OnEncodingChanged)
- ON_COMMAND(IDC_BUTTON1, &CRawSampleDlg::OnAutodetectFormat)
- END_MESSAGE_MAP()
- void CRawSampleDlg::DoDataExchange(CDataExchange *pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CRawSampleDlg)
- DDX_Control(pDX, IDC_SPIN1, m_SpinOffset);
- //}}AFX_DATA_MAP
- }
- BOOL CRawSampleDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- if(const auto filename = m_file.GetOptionalFileName(); filename)
- {
- CString title;
- GetWindowText(title);
- title += _T(" - ") + filename->GetFullFileName().ToCString();
- SetWindowText(title);
- }
- m_SpinOffset.SetRange32(0, mpt::saturate_cast<int>(m_file.GetLength() - 1u));
- UpdateDialog();
- return TRUE;
- }
- void CRawSampleDlg::OnOK()
- {
- const int bitDepth = GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO4);
- const int channels = GetCheckedRadioButton(IDC_RADIO5, IDC_RADIO6);
- const int encoding = GetCheckedRadioButton(IDC_RADIO7, IDC_RADIO10);
- const int endianness = GetCheckedRadioButton(IDC_RADIO11, IDC_RADIO12);
- if(bitDepth == IDC_RADIO1)
- m_format |= SampleIO::_8bit;
- else if(bitDepth == IDC_RADIO2)
- m_format |= SampleIO::_16bit;
- else if(bitDepth == IDC_RADIO3)
- m_format |= SampleIO::_24bit;
- else if(bitDepth == IDC_RADIO4)
- m_format |= SampleIO::_32bit;
- if(channels == IDC_RADIO5)
- m_format |= SampleIO::mono;
- else if(channels == IDC_RADIO6)
- m_format |= SampleIO::stereoInterleaved;
- if(encoding == IDC_RADIO7)
- m_format |= SampleIO::signedPCM;
- else if(encoding == IDC_RADIO8)
- m_format |= SampleIO::unsignedPCM;
- else if(encoding == IDC_RADIO9)
- m_format |= SampleIO::deltaPCM;
- else if(encoding == IDC_RADIO10)
- m_format |= SampleIO::floatPCM;
- if(endianness == IDC_RADIO11)
- m_format |= SampleIO::littleEndian;
- else if(endianness == IDC_RADIO12)
- m_format |= SampleIO::bigEndian;
- m_rememberFormat = IsDlgButtonChecked(IDC_CHK_REMEMBERSETTINGS) != BST_UNCHECKED;
- m_offset = GetDlgItemInt(IDC_EDIT1, nullptr, FALSE);
- CDialog::OnOK();
- }
- void CRawSampleDlg::UpdateDialog()
- {
- const int bitDepthID = IDC_RADIO1 + m_format.GetBitDepth() / 8 - 1;
- CheckRadioButton(IDC_RADIO1, IDC_RADIO4, bitDepthID);
- CheckRadioButton(IDC_RADIO5, IDC_RADIO6, (m_format.GetChannelFormat() == SampleIO::mono) ? IDC_RADIO5 : IDC_RADIO6);
- int encodingID = IDC_RADIO7;
- switch(m_format.GetEncoding())
- {
- case SampleIO::signedPCM: encodingID = IDC_RADIO7; break;
- case SampleIO::unsignedPCM: encodingID = IDC_RADIO8; break;
- case SampleIO::deltaPCM: encodingID = IDC_RADIO9; break;
- case SampleIO::floatPCM: encodingID = IDC_RADIO10; break;
- default: MPT_ASSERT_NOTREACHED();
- }
- CheckRadioButton(IDC_RADIO7, IDC_RADIO10, encodingID);
- CheckRadioButton(IDC_RADIO11, IDC_RADIO12, (m_format.GetEndianness() == SampleIO::littleEndian) ? IDC_RADIO11 : IDC_RADIO12);
- CheckDlgButton(IDC_CHK_REMEMBERSETTINGS, (m_rememberFormat ? BST_CHECKED : BST_UNCHECKED));
- SetDlgItemInt(IDC_EDIT1, m_offset, FALSE);
- OnBitDepthChanged(bitDepthID);
- OnEncodingChanged(encodingID);
- }
- void CRawSampleDlg::OnBitDepthChanged(UINT id)
- {
- const auto bits = (id - IDC_RADIO1 + 1) * 8;
- // 8-bit: endianness doesn't matter
- BOOL enableEndianness = (bits == 8) ? FALSE : TRUE;
- GetDlgItem(IDC_RADIO11)->EnableWindow(enableEndianness);
- GetDlgItem(IDC_RADIO12)->EnableWindow(enableEndianness);
- if(bits == 8)
- CheckRadioButton(IDC_RADIO11, IDC_RADIO12, IDC_RADIO11);
- const BOOL hasUnsignedDelta = (bits <= 16) ? TRUE : FALSE;
- const BOOL hasFloat = (bits == 32) ? TRUE : FALSE;
- GetDlgItem(IDC_RADIO8)->EnableWindow(hasUnsignedDelta);
- GetDlgItem(IDC_RADIO9)->EnableWindow(hasUnsignedDelta);
- GetDlgItem(IDC_RADIO10)->EnableWindow(hasFloat);
- const int encoding = GetCheckedRadioButton(IDC_RADIO7, IDC_RADIO10);
- if((encoding == IDC_RADIO8 && !hasUnsignedDelta)
- || (encoding == IDC_RADIO9 && !hasUnsignedDelta)
- || (encoding == IDC_RADIO10 && !hasFloat))
- CheckRadioButton(IDC_RADIO7, IDC_RADIO10, IDC_RADIO7);
- }
- void CRawSampleDlg::OnEncodingChanged(UINT id)
- {
- const bool isUnsignedDelta = (id == IDC_RADIO8) || (id == IDC_RADIO9);
- const bool isFloat = (id == IDC_RADIO10);
- GetDlgItem(IDC_RADIO1)->EnableWindow(isFloat ? FALSE : TRUE);
- GetDlgItem(IDC_RADIO2)->EnableWindow(isFloat ? FALSE : TRUE);
- GetDlgItem(IDC_RADIO3)->EnableWindow((isFloat || isUnsignedDelta) ? FALSE : TRUE);
- GetDlgItem(IDC_RADIO4)->EnableWindow(isUnsignedDelta ? FALSE : TRUE);
- const int bitDepth = GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO4);
- if(bitDepth != IDC_RADIO4 && isFloat)
- CheckRadioButton(IDC_RADIO1, IDC_RADIO4, IDC_RADIO4);
- if((bitDepth == IDC_RADIO3 || bitDepth == IDC_RADIO4) && isUnsignedDelta)
- CheckRadioButton(IDC_RADIO1, IDC_RADIO4, IDC_RADIO1);
- }
- class AutodetectFormatDlg : public CProgressDialog
- {
- CRawSampleDlg &m_parent;
- public:
- SampleIO m_bestFormat;
- AutodetectFormatDlg(CRawSampleDlg &parent)
- : CProgressDialog(&parent)
- , m_parent(parent) {}
- void Run() override
- {
- // Probed raw formats... little-endian and stereo versions are automatically checked as well.
- static constexpr SampleIO ProbeFormats[] =
- {
- // 8-Bit
- {SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM},
- {SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::unsignedPCM},
- {SampleIO::_8bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::deltaPCM},
- // 16-Bit
- {SampleIO::_16bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM},
- {SampleIO::_16bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::unsignedPCM},
- {SampleIO::_16bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::deltaPCM},
- // 24-Bit
- {SampleIO::_24bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM},
- // 32-Bit
- {SampleIO::_32bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::signedPCM},
- {SampleIO::_32bit, SampleIO::mono, SampleIO::bigEndian, SampleIO::floatPCM},
- };
- SetTitle(_T("Raw Import"));
- SetText(_T("Determining raw format..."));
- SetRange(0, std::size(ProbeFormats) * 4);
- double bestError = DBL_MAX;
- uint64 progress = 0;
- for(SampleIO format : ProbeFormats)
- {
- for(const auto endianness : {SampleIO::littleEndian, SampleIO::bigEndian})
- {
- if(endianness == SampleIO::bigEndian && format.GetBitDepth() == SampleIO::_8bit)
- continue;
- format |= endianness;
- for(const auto channels : {SampleIO::mono, SampleIO::stereoInterleaved})
- {
- format |= channels;
- ModSample sample;
- m_parent.m_file.Seek(m_parent.m_offset);
- const auto bytesPerSample = format.GetNumChannels() * format.GetBitDepth() / 8u;
- sample.nLength = mpt::saturate_cast<SmpLength>(m_parent.m_file.BytesLeft() / bytesPerSample);
- if(!format.ReadSample(sample, m_parent.m_file))
- continue;
- const uint8 numChannels = sample.GetNumChannels();
- double error = 0.0;
- for(uint8 chn = 0; chn < numChannels; chn++)
- {
- const auto ComputeSampleError = [](auto *v, SmpLength length, uint8 numChannels)
- {
- const double factor = 1.0 / (1u << (sizeof(*v) * 8u - 1u));
- double error = 0.0;
- int32 prev = 0;
- for(SmpLength i = length; i != 0; i--, v += numChannels)
- {
- auto diff = (*v - prev) * factor;
- error += diff * diff;
- prev = *v;
- }
- return error;
- };
- if(sample.uFlags[CHN_16BIT])
- error += ComputeSampleError(sample.sample16() + chn, sample.nLength, numChannels);
- else
- error += ComputeSampleError(sample.sample8() + chn, sample.nLength, numChannels);
- }
- sample.FreeSample();
- double errorFactor = format.GetBitDepth() * format.GetBitDepth() / 64;
- // Delta PCM often produces slightly worse error compared to signed PCM for real delta samples, so give it a bit of an advantage.
- if(format.GetEncoding() == SampleIO::deltaPCM)
- errorFactor *= 0.75;
- error *= errorFactor;
- if(error < bestError)
- {
- bestError = error;
- m_bestFormat = format;
- }
- SetProgress(++progress);
- ProcessMessages();
- if(m_abort)
- {
- EndDialog(IDCANCEL);
- return;
- }
- }
- }
- }
- EndDialog(IDOK);
- }
- };
- void CRawSampleDlg::OnAutodetectFormat()
- {
- m_offset = GetDlgItemInt(IDC_EDIT1, nullptr, FALSE);
- AutodetectFormatDlg dlg(*this);
- if(dlg.DoModal() == IDOK)
- {
- m_format = dlg.m_bestFormat;
- UpdateDialog();
- }
- }
- /////////////////////////////////////////////////////////////////////////
- // Add silence / resize sample dialog
- BEGIN_MESSAGE_MAP(AddSilenceDlg, CDialog)
- ON_CBN_SELCHANGE(IDC_COMBO1, &AddSilenceDlg::OnUnitChanged)
- ON_COMMAND(IDC_RADIO_ADDSILENCE_BEGIN, &AddSilenceDlg::OnEditModeChanged)
- ON_COMMAND(IDC_RADIO_ADDSILENCE_END, &AddSilenceDlg::OnEditModeChanged)
- ON_COMMAND(IDC_RADIO_RESIZETO, &AddSilenceDlg::OnEditModeChanged)
- ON_COMMAND(IDC_RADIO1, &AddSilenceDlg::OnEditModeChanged)
- END_MESSAGE_MAP()
- SmpLength AddSilenceDlg::m_addSamples = 32;
- SmpLength AddSilenceDlg::m_createSamples = 64;
- AddSilenceDlg::AddSilenceDlg(CWnd *parent, SmpLength origLength, uint32 sampleRate, bool allowOPL)
- : CDialog(IDD_ADDSILENCE, parent)
- , m_numSamples(m_addSamples)
- , m_sampleRate(sampleRate)
- , m_allowOPL(allowOPL)
- {
- if(origLength > 0)
- {
- m_length = origLength;
- m_editOption = kSilenceAtEnd;
- } else
- {
- m_length = m_createSamples;
- m_editOption = kResize;
- }
- }
- BOOL AddSilenceDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- CSpinButtonCtrl *spin = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_ADDSILENCE);
- if(spin)
- {
- spin->SetRange32(0, int32_max);
- spin->SetPos32(m_numSamples);
- }
- CComboBox *box = (CComboBox *)GetDlgItem(IDC_COMBO1);
- if(box)
- {
- box->AddString(_T("samples"));
- box->AddString(_T("ms"));
- box->SetCurSel(m_unit);
- if(m_sampleRate == 0)
- {
- // Can't do any conversions if samplerate is unknown
- box->EnableWindow(FALSE);
- }
- }
- int buttonID = IDC_RADIO_ADDSILENCE_END;
- switch(m_editOption)
- {
- case kSilenceAtBeginning: buttonID = IDC_RADIO_ADDSILENCE_BEGIN; break;
- case kSilenceAtEnd: buttonID = IDC_RADIO_ADDSILENCE_END; break;
- case kResize: buttonID = IDC_RADIO_RESIZETO; break;
- }
- CheckDlgButton(buttonID, BST_CHECKED);
- SetDlgItemInt(IDC_EDIT_ADDSILENCE, (m_editOption == kResize) ? m_length : m_numSamples, FALSE);
- GetDlgItem(IDC_RADIO1)->EnableWindow(m_allowOPL ? TRUE : FALSE);
- return TRUE;
- }
- void AddSilenceDlg::OnOK()
- {
- m_numSamples = GetDlgItemInt(IDC_EDIT_ADDSILENCE, nullptr, FALSE);
- if(m_unit == kMilliseconds)
- {
- m_numSamples = Util::muldivr_unsigned(m_numSamples, m_sampleRate, 1000);
- }
- switch(m_editOption = GetEditMode())
- {
- case kSilenceAtBeginning:
- case kSilenceAtEnd:
- m_addSamples = m_numSamples;
- break;
- case kResize:
- m_createSamples = m_numSamples;
- break;
- }
- CDialog::OnOK();
- }
- void AddSilenceDlg::OnEditModeChanged()
- {
- AddSilenceOptions newEditOption = GetEditMode();
- GetDlgItem(IDC_EDIT_ADDSILENCE)->EnableWindow((newEditOption == kOPLInstrument) ? FALSE : TRUE);
- if(newEditOption != kResize && m_editOption == kResize)
- {
- // Switch to "add silence"
- m_length = GetDlgItemInt(IDC_EDIT_ADDSILENCE);
- SetDlgItemInt(IDC_EDIT_ADDSILENCE, m_numSamples);
- } else if(newEditOption == kResize && m_editOption != kResize)
- {
- // Switch to "resize"
- m_numSamples = GetDlgItemInt(IDC_EDIT_ADDSILENCE);
- SetDlgItemInt(IDC_EDIT_ADDSILENCE, m_length);
- }
- m_editOption = newEditOption;
- }
- void AddSilenceDlg::OnUnitChanged()
- {
- const auto unit = static_cast<Unit>(static_cast<CComboBox*>(GetDlgItem(IDC_COMBO1))->GetCurSel());
- if(m_unit == unit)
- return;
- m_unit = unit;
- SmpLength duration = GetDlgItemInt(IDC_EDIT_ADDSILENCE);
- if(m_unit == kSamples)
- {
- // Convert from milliseconds
- duration = Util::muldivr_unsigned(duration, m_sampleRate, 1000);
- } else
- {
- // Convert from samples
- duration = Util::muldivr_unsigned(duration, 1000, m_sampleRate);
- }
- SetDlgItemInt(IDC_EDIT_ADDSILENCE, duration);
- }
- AddSilenceDlg::AddSilenceOptions AddSilenceDlg::GetEditMode() const
- {
- if(IsDlgButtonChecked(IDC_RADIO_ADDSILENCE_BEGIN)) return kSilenceAtBeginning;
- else if(IsDlgButtonChecked(IDC_RADIO_ADDSILENCE_END)) return kSilenceAtEnd;
- else if(IsDlgButtonChecked(IDC_RADIO_RESIZETO)) return kResize;
- else if(IsDlgButtonChecked(IDC_RADIO1)) return kOPLInstrument;
- MPT_ASSERT_NOTREACHED();
- return kSilenceAtEnd;
- }
- /////////////////////////////////////////////////////////////////////////
- // Sample grid dialog
- void CSampleGridDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CSampleGridDlg)
- DDX_Control(pDX, IDC_EDIT1, m_EditSegments);
- DDX_Control(pDX, IDC_SPIN1, m_SpinSegments);
- //}}AFX_DATA_MAP
- }
- BOOL CSampleGridDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- m_SpinSegments.SetRange32(0, m_nMaxSegments);
- m_SpinSegments.SetPos(m_nSegments);
- SetDlgItemInt(IDC_EDIT1, m_nSegments, FALSE);
- GetDlgItem(IDC_EDIT1)->SetFocus();
- return TRUE;
- }
- void CSampleGridDlg::OnOK()
- {
- m_nSegments = GetDlgItemInt(IDC_EDIT1, NULL, FALSE);
- CDialog::OnOK();
- }
- /////////////////////////////////////////////////////////////////////////
- // Sample cross-fade dialog
- uint32 CSampleXFadeDlg::m_fadeLength = 20000;
- uint32 CSampleXFadeDlg::m_fadeLaw = 50000;
- bool CSampleXFadeDlg::m_afterloopFade = true;
- bool CSampleXFadeDlg::m_useSustainLoop = false;
- BEGIN_MESSAGE_MAP(CSampleXFadeDlg, CDialog)
- ON_WM_HSCROLL()
- ON_COMMAND(IDC_RADIO1, &CSampleXFadeDlg::OnLoopTypeChanged)
- ON_COMMAND(IDC_RADIO2, &CSampleXFadeDlg::OnLoopTypeChanged)
- ON_EN_CHANGE(IDC_EDIT1, &CSampleXFadeDlg::OnFadeLengthChanged)
- ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CSampleXFadeDlg::OnToolTipText)
- END_MESSAGE_MAP()
- void CSampleXFadeDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CSampleGridDlg)
- DDX_Control(pDX, IDC_EDIT1, m_EditSamples);
- DDX_Control(pDX, IDC_SPIN1, m_SpinSamples);
- DDX_Control(pDX, IDC_SLIDER1, m_SliderLength);
- DDX_Control(pDX, IDC_SLIDER2, m_SliderFadeLaw);
- DDX_Control(pDX, IDC_RADIO1, m_RadioNormalLoop);
- DDX_Control(pDX, IDC_RADIO2, m_RadioSustainLoop);
- //}}AFX_DATA_MAP
- }
- BOOL CSampleXFadeDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- const bool hasNormal = m_sample.uFlags[CHN_LOOP] && m_sample.nLoopStart > 0;
- const bool hasSustain = m_sample.uFlags[CHN_SUSTAINLOOP] && m_sample.nSustainStart > 0;
- const bool hasBothLoops = hasNormal && hasSustain;
- m_RadioNormalLoop.EnableWindow(hasBothLoops);
- m_RadioSustainLoop.EnableWindow(hasBothLoops);
- CheckRadioButton(IDC_RADIO1, IDC_RADIO2, ((m_useSustainLoop && hasSustain) || !hasNormal) ? IDC_RADIO2 : IDC_RADIO1);
- m_SliderLength.SetRange(0, 100000);
- m_SliderLength.SetPos(m_fadeLength);
- m_SliderFadeLaw.SetRange(0, 100000);
- m_SliderFadeLaw.SetPos(m_fadeLaw);
- OnLoopTypeChanged();
- return TRUE;
- }
- void CSampleXFadeDlg::OnOK()
- {
- m_fadeLength = m_SliderLength.GetPos();
- m_fadeLaw = m_SliderFadeLaw.GetPos();
- m_afterloopFade = IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED;
- m_useSustainLoop = IsDlgButtonChecked(IDC_RADIO2) != BST_UNCHECKED;
- Limit(m_fadeLength, uint32(0), uint32(100000));
- CDialog::OnOK();
- }
- void CSampleXFadeDlg::OnLoopTypeChanged()
- {
- SmpLength loopStart = m_sample.nLoopStart, loopEnd = m_sample.nLoopEnd;
- if(IsDlgButtonChecked(IDC_RADIO2))
- {
- loopStart = m_sample.nSustainStart;
- loopEnd = m_sample.nSustainEnd;
- }
- m_maxLength = std::min({ m_sample.nLength, loopStart, loopEnd / 2u });
- m_loopLength = loopEnd - loopStart;
- m_editLocked = true;
- m_SpinSamples.SetRange32(0, std::min(m_loopLength, m_maxLength));
- GetDlgItem(IDC_EDIT1)->SetFocus();
- CheckDlgButton(IDC_CHECK1, m_afterloopFade ? BST_CHECKED : BST_UNCHECKED);
- SmpLength numSamples = PercentToSamples(m_SliderLength.GetPos());
- numSamples = std::min({ numSamples, m_loopLength, m_maxLength });
- m_SpinSamples.SetPos(numSamples);
- SetDlgItemInt(IDC_EDIT1, numSamples, FALSE);
- m_editLocked = false;
- }
- void CSampleXFadeDlg::OnFadeLengthChanged()
- {
- if(m_editLocked) return;
- SmpLength numSamples = GetDlgItemInt(IDC_EDIT1, NULL, FALSE);
- numSamples = std::min({ numSamples, m_loopLength, m_maxLength });
- m_SliderLength.SetPos(SamplesToPercent(numSamples));
- }
- void CSampleXFadeDlg::OnHScroll(UINT, UINT, CScrollBar *sb)
- {
- if(sb == (CScrollBar *)(&m_SliderLength))
- {
- m_editLocked = true;
- SmpLength numSamples = PercentToSamples(m_SliderLength.GetPos());
- if(numSamples > m_maxLength)
- {
- numSamples = m_maxLength;
- m_SliderLength.SetPos(SamplesToPercent(numSamples));
- }
- m_SpinSamples.SetPos(numSamples);
- SetDlgItemInt(IDC_EDIT1, numSamples, FALSE);
- m_editLocked = false;
- }
- }
- BOOL CSampleXFadeDlg::OnToolTipText(UINT, NMHDR *pNMHDR, LRESULT *pResult)
- {
- TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
- UINT_PTR nID = pNMHDR->idFrom;
- if(pTTT->uFlags & TTF_IDISHWND)
- {
- // idFrom is actually the HWND of the tool
- nID = (UINT_PTR)::GetDlgCtrlID((HWND)nID);
- }
- switch(nID)
- {
- case IDC_SLIDER1:
- {
- uint32 percent = m_SliderLength.GetPos();
- wsprintf(pTTT->szText, _T("%u.%03u%% of the loop (%u samples)"), percent / 1000, percent % 1000, PercentToSamples(percent));
- }
- break;
- case IDC_SLIDER2:
- _tcscpy(pTTT->szText, _T("Slide towards constant power for fixing badly looped samples."));
- break;
- default:
- return FALSE;
- }
- *pResult = 0;
- // bring the tooltip window above other popup windows
- ::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
- SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////
- // Resampling dialog
- CResamplingDlg::ResamplingOption CResamplingDlg::m_lastChoice = CResamplingDlg::Upsample;
- uint32 CResamplingDlg::m_lastFrequency = 0;
- bool CResamplingDlg::m_updatePatterns = false;
- BEGIN_MESSAGE_MAP(CResamplingDlg, CDialog)
- ON_EN_SETFOCUS(IDC_EDIT1, &CResamplingDlg::OnFocusEdit)
- END_MESSAGE_MAP()
- BOOL CResamplingDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- SetWindowText(m_resampleAll ? _T("Resample All") : _T("Resample"));
- CheckRadioButton(IDC_RADIO1, IDC_RADIO3, IDC_RADIO1 + m_lastChoice);
- if(m_frequency > 0)
- {
- TCHAR s[32];
- wsprintf(s, _T("&Upsample (%u Hz)"), m_frequency * 2);
- SetDlgItemText(IDC_RADIO1, s);
- wsprintf(s, _T("&Downsample (%u Hz)"), m_frequency / 2);
- SetDlgItemText(IDC_RADIO2, s);
- if(!m_lastFrequency)
- m_lastFrequency = m_frequency;
- }
- if(!m_lastFrequency)
- m_lastFrequency = 48000;
- SetDlgItemInt(IDC_EDIT1, m_lastFrequency, FALSE);
- CSpinButtonCtrl *spin = static_cast<CSpinButtonCtrl *>(GetDlgItem(IDC_SPIN1));
- spin->SetRange32(1, 999999);
- spin->SetPos32(m_lastFrequency);
- CComboBox *cbnResampling = static_cast<CComboBox *>(GetDlgItem(IDC_COMBO_FILTER));
- cbnResampling->SetRedraw(FALSE);
- const auto resamplingModes = Resampling::AllModesWithDefault();
- for(auto mode : resamplingModes)
- {
- CString desc = _T("r8brain (High Quality)");
- if(mode != SRCMODE_DEFAULT)
- desc = CTrackApp::GetResamplingModeName(mode, 1, true);
- int index = cbnResampling->AddString(desc);
- cbnResampling->SetItemData(index, mode);
- if(m_srcMode == mode)
- cbnResampling->SetCurSel(index);
- }
- cbnResampling->SetRedraw(TRUE);
- CheckDlgButton(IDC_CHECK1, m_updatePatterns ? BST_CHECKED : BST_UNCHECKED);
- return TRUE;
- }
- void CResamplingDlg::OnOK()
- {
- const int choice = GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO3);
- if(choice == IDC_RADIO1)
- {
- m_lastChoice = Upsample;
- m_frequency *= 2;
- } else if(choice == IDC_RADIO2)
- {
- m_lastChoice = Downsample;
- m_frequency /= 2;
- } else
- {
- m_lastChoice = Custom;
- uint32 newFrequency = GetDlgItemInt(IDC_EDIT1, NULL, FALSE);
- if(newFrequency > 0)
- {
- m_lastFrequency = m_frequency = newFrequency;
- } else
- {
- MessageBeep(MB_ICONWARNING);
- GetDlgItem(IDC_EDIT1)->SetFocus();
- return;
- }
- }
- CComboBox *cbnResampling = static_cast<CComboBox *>(GetDlgItem(IDC_COMBO_FILTER));
- m_srcMode = static_cast<ResamplingMode>(cbnResampling->GetItemData(cbnResampling->GetCurSel()));
- m_updatePatterns = IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED;
- CDialog::OnOK();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////
- // Sample mix dialog
- SmpLength CMixSampleDlg::sampleOffset = 0;
- int CMixSampleDlg::amplifyOriginal = 50;
- int CMixSampleDlg::amplifyMix = 50;
- void CMixSampleDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CMixSampleDlg)
- DDX_Control(pDX, IDC_EDIT_OFFSET, m_EditOffset);
- DDX_Control(pDX, IDC_SPIN_OFFSET, m_SpinOffset);
- DDX_Control(pDX, IDC_SPIN_SAMPVOL1, m_SpinVolOriginal);
- DDX_Control(pDX, IDC_SPIN_SAMPVOL2, m_SpinVolMix);
- //}}AFX_DATA_MAP
- }
- CMixSampleDlg::CMixSampleDlg(CWnd *parent)
- : CDialog(IDD_MIXSAMPLES, parent)
- { }
- BOOL CMixSampleDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Offset
- m_SpinOffset.SetRange32(0, MAX_SAMPLE_LENGTH);
- SetDlgItemInt(IDC_EDIT_OFFSET, sampleOffset);
- // Volumes
- m_SpinVolOriginal.SetRange(-10000, 10000);
- m_SpinVolMix.SetRange(-10000, 10000);
- m_EditVolOriginal.SubclassDlgItem(IDC_EDIT_SAMPVOL1, this);
- m_EditVolOriginal.AllowNegative(true);
- m_EditVolMix.SubclassDlgItem(IDC_EDIT_SAMPVOL2, this);
- m_EditVolMix.AllowNegative(true);
- SetDlgItemInt(IDC_EDIT_SAMPVOL1, amplifyOriginal);
- SetDlgItemInt(IDC_EDIT_SAMPVOL2, amplifyMix);
- return TRUE;
- }
- void CMixSampleDlg::OnOK()
- {
- CDialog::OnOK();
- sampleOffset = Clamp<SmpLength, SmpLength>(GetDlgItemInt(IDC_EDIT_OFFSET), 0, MAX_SAMPLE_LENGTH);
- amplifyOriginal = Clamp<int, int>(GetDlgItemInt(IDC_EDIT_SAMPVOL1), -10000, 10000);
- amplifyMix = Clamp<int, int>(GetDlgItemInt(IDC_EDIT_SAMPVOL2), -10000, 10000);
- }
- OPENMPT_NAMESPACE_END
|