diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 5e69194..e8b4be2 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -4,5 +4,6 @@
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 58b2825..704dc7d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,7 +43,7 @@ add_executable(bmhelper WIN32
src/smf_event.cpp
src/smf_io.h
src/srcview.cpp
- src/srcview.h src/AudioSplitter.cpp src/AudioSplitter.h src/wavsplit.cpp src/wavsplit.h)
+ src/srcview.h src/AudioSplitter.cpp src/AudioSplitter.h src/wavsplit.cpp src/wavsplit.h src/divsettingdialog.h)
include(${wxWidgets_USE_FILE})
target_link_libraries(bmhelper ${wxWidgets_LIBRARIES} ${LIBSNDFILE_LIBRARIES})
diff --git a/src/divedit.cpp b/src/divedit.cpp
index e6a73ca..645fb24 100644
--- a/src/divedit.cpp
+++ b/src/divedit.cpp
@@ -6,6 +6,7 @@
#include "AudioSplitter.h"
#include
#include
+#include "divsettingdialog.h"
enum {
ID_SmfOutput,
@@ -387,4 +388,17 @@ void DivisionEditor::OnOpenAudioSplitter(wxCommandEvent &event) {
splitter->Show();
}
+bool DivisionEditor::OnDivRegenerate(wxMenuEvent &event) {
+ if (!division) return false;
+ DivisionSetting setting(division->get_name(), division->get_quantize());
+
+ DivisionSettingDialog dialog(frame, setting, division->get_quantize());
+ if (dialog.ShowModal() != wxID_OK)
+ return false;
+
+ dialog.GetSetting(setting);
+ division->change_division_settings(setting);
+ return true;
+}
+
diff --git a/src/division.cpp b/src/division.cpp
index 6cd9890..c1bb6c0 100644
--- a/src/division.cpp
+++ b/src/division.cpp
@@ -190,6 +190,17 @@ static void sort_notes(
Division::Division(Project *_project, MidiData &src, const DivisionSetting &setting)
: MidiData(src.get_quantize()), project(_project), name(setting.name), zz_enabled(setting.zz_definition) {
+ divide_from_data(src, setting);
+}
+
+void Division::divide_from_data(MidiData &src, const DivisionSetting &setting, bool copy) {
+ if (copy)
+ src_data = src; // store a copy of the src data...
+
+ init(); /* clean ourselves up */
+
+ name = setting.name;
+
std::vector temp_divs;
std::vector src2div(src.notes_count());
src2def.resize(src.notes_count());
@@ -205,21 +216,27 @@ Division::Division(Project *_project, MidiData &src, const DivisionSetting &sett
note.referrers.push_back(i);
src2div[i] = i;
}
+
// Midiデータにそのまま配置
for (size_t i = 0; i < temp_divs.size(); i++) {
note_push_back(
MidiNoteEvent(src.notes(i).position + setting.head_margin, temp_divs[i].gate, temp_divs[i].nn,
temp_divs[i].vel));
}
- if (src.notes_count() > 0) head_margin = src.notes(0).position+setting.head_margin;
+
+ if (src.notes_count() > 0) head_margin = src.notes(0).position + setting.head_margin;
} else {
// 分割
- ThresholdSetting thresholds{};
- thresholds.gate = setting.gate_threshold;
- thresholds.vel = setting.velocity_threshold;
+ ThresholdSetting thresholds {
+ static_cast(setting.gate_threshold),
+ static_cast(setting.velocity_threshold)
+ };
+
divide_notes(src, src2div, temp_divs, thresholds);
+
// ソート
sort_notes(temp_divs, src2div, setting.sort_type);
+
// Midiデータに流し込み
int position = setting.head_margin;
for (auto & temp_div : temp_divs) {
@@ -228,6 +245,7 @@ Division::Division(Project *_project, MidiData &src, const DivisionSetting &sett
int b = position % get_quantize();
if (b) position += get_quantize() - b;
}
+
head_margin = setting.head_margin;
}
@@ -258,18 +276,19 @@ Division::Division(Project *_project, MidiData &src, const DivisionSetting &sett
} else {
mln = 1; // 多重定義しない
}
+
size_t id_i = definitions.size();
for (size_t b = 0; b < mln; b++) {
definitions.push_back(Definition(zz, i));
if (setting.zz_definition) zz++; else zz.increment_in_ff();
}
+
size_t b = 0;
for (int referrer : temp_divs[i].referrers) {
src2def[referrer] = id_i + b;
if (++b == mln) b = 0;
}
}
-
}
@@ -366,6 +385,7 @@ static const NodeName _name_ = StringToNodeName("name");
static const NodeName _s2df_ = StringToNodeName("s2df");
static const NodeName _dfnt_ = StringToNodeName("dfnt");
static const NodeName _zzen_ = StringToNodeName("zzen");
+static const NodeName _srcd_ = StringToNodeName("Srcd"); /* source data (first letter caps = list) */
struct BmsOffsetData {
bool zz_enabled;
@@ -400,6 +420,8 @@ bool Division::read_tree(TreeNode &node) {
sub.get_data(&data, sizeof(BmsOffsetData));
zz_enabled = data.zz_enabled;
}
+ } else if (sub.get_name() == _srcd_) {
+ src_data.read_tree(sub);
}
}
return true;
@@ -430,8 +452,28 @@ bool Division::write_tree(TreeNode &node) {
node.push_back(_zzen_);
node.back().set_data(&offset_data, sizeof(BmsOffsetData));
+
+ node.push_back(_srcd_);
+ src_data.write_tree(node.back());
+
return true;
}
+void Division::change_division_settings(const DivisionSetting &setting) {
+ divide_from_data(src_data, setting, false);
+}
+DivisionSetting::DivisionSetting(const wxString &name, size_t quantize) {
+ this->name = name;
+ src_copy = false;
+ head_margin = 0;
+ min_interval = quantize*1;
+ sort_type = DivisionSetting::SORT_NN_GATE_V;
+ gate_threshold = quantize/8;
+ velocity_threshold = 5;
+ zz_definition = true;
+ ml_definition = true;
+ start_definition = 1;
+ ml_threshold = quantize/2;
+}
diff --git a/src/division.h b/src/division.h
index 6f1b20d..f7e0b12 100644
--- a/src/division.h
+++ b/src/division.h
@@ -33,6 +33,7 @@ struct DivisionSetting{
ZZNumber start_definition; // �J�n��`�ԍ�
int ml_threshold; // ���d��`���邩�ǂ����̃m�[�g�Ԋu��臒l(���l���ݒ�B���x�̏ꍇ�͑��d��`���Ȃ�)
+ DivisionSetting(const wxString &name, size_t quantize);
};
@@ -60,6 +61,8 @@ class Division : public MidiData{
int head_margin;
bool zz_enabled;
+ MidiData src_data;
+
//void _divide_notes(std::vector &src2div, std::vector &temp_divs, ThresholdSetting &thresholds);
//void _sort_notes(std::vector &temp_divs, DivisionSetting::SortType sort_type);
@@ -67,7 +70,7 @@ class Division : public MidiData{
Division(Project *_project);
Division(Project *_project, MidiData &src, const DivisionSetting &setting);
void init() override {
- //MidiData::init();
+ MidiData::init();
name.clear();
src2def.clear();
definitions.clear();
@@ -94,6 +97,9 @@ class Division : public MidiData{
void def_transpose_up();
void def_transpose_down();
void def_transpose_to(ZZNumber nbegin);
+
+ void divide_from_data(MidiData &src, const DivisionSetting &setting, bool copy = true);
+ void change_division_settings(const DivisionSetting &setting);
};
diff --git a/src/divsettingdialog.h b/src/divsettingdialog.h
new file mode 100644
index 0000000..262463f
--- /dev/null
+++ b/src/divsettingdialog.h
@@ -0,0 +1,64 @@
+#ifndef BMHELPER_DIVSETTINGDIALOG_H
+#define BMHELPER_DIVSETTINGDIALOG_H
+
+class DivisionSettingDialog : public wxDialog{
+ enum{
+ ID_NameLabel = 1,
+ ID_NameInput = 2,
+ ID_MidiBox = 30,
+ ID_ScpyCheck = 29,
+ ID_MhmgLabel = 32,
+ ID_MhmgInput = 33,
+ ID_MintLabel = 3,
+ ID_MintInput = 4,
+ ID_SortLabel = 5,
+ ID_SortCombo = 6,
+ ID_ThrsLabel = 20,
+ ID_TgatLabel = 7,
+ ID_TgatInput = 8,
+ ID_TvelLabel = 9,
+ ID_TvelInput = 10,
+ ID_DefnBox = 31,
+// ID_DfzzLabel = 11,
+ ID_DfzzCheck = 12,
+ ID_DfmlCheck = 21,
+ ID_DfstLabel = 13,
+ ID_DfstInput = 14,
+ ID_DfmtLabel = 22,
+ ID_DfmtInput = 23
+ };
+ wxStaticText *name_label;
+ wxTextCtrl *name_input;
+ wxStaticBox *midi_box;
+ wxCheckBox *scpy_check;
+ wxStaticText *mhmg_label;
+ wxTextCtrl *mhmg_input;
+ wxStaticText *mint_label;
+ wxTextCtrl *mint_input;
+ wxStaticText *sort_label;
+ wxComboBox *sort_combo;
+ wxStaticText *thrs_label;
+ wxStaticText *tgat_label;
+ wxTextCtrl *tgat_input;
+ wxStaticText *tvel_label;
+ wxTextCtrl *tvel_input;
+ wxStaticBox *defn_box;
+// wxStaticText *dfzz_label;
+ wxCheckBox *dfzz_check;
+ wxCheckBox *dfml_check;
+ wxStaticText *dfst_label;
+ wxTextCtrl *dfst_input;
+ wxStaticText *dfmt_label;
+ wxTextCtrl *dfmt_input;
+ wxButton *button_ok, *button_cancel;
+ int quantize;
+ static const int _lm=15, _tm=5, _lw=25, _lb=30, _fc=150, _sc=130, _bw=5, _cw=25;
+public:
+ DivisionSettingDialog(wxWindow *owner, DivisionSetting setting, int _quantize);
+ void GetSetting(DivisionSetting &setting);
+ void OnScpyCheck(wxCommandEvent &WXUNUSED(ev));
+ void OnOK(wxCommandEvent &WXUNUSED(ev));
+ wxDECLARE_EVENT_TABLE();
+};
+
+#endif //BMHELPER_DIVSETTINGDIALOG_H
diff --git a/src/divview.cpp b/src/divview.cpp
index f45e01c..539529b 100644
--- a/src/divview.cpp
+++ b/src/divview.cpp
@@ -4,6 +4,7 @@
#include "divview.h"
#include
+#include "divsettingdialog.h"
enum{
@@ -24,7 +25,7 @@ END_EVENT_TABLE()
DivisionsView::DivisionsView(FrameWindow *_frame, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxWindow(parent, id, pos, size, style, name), frame(_frame),
-new_div(0), divisions(0), editor(0)
+new_div(nullptr), divisions(nullptr), editor(nullptr)
{
SetWindowStyle(wxBORDER_SIMPLE | wxCLIP_CHILDREN);
@@ -116,9 +117,10 @@ void DivisionsView::OnDeleteDivision(wxMenuEvent &WXUNUSED(event)){
void DivisionsView::DivisionChanged(){
int selection = divisions->GetSelection();
if (selection == wxNOT_FOUND){
- editor->SetDivision(0);
- frame->UpdateDivision(0);
+ editor->SetDivision(nullptr);
+ frame->UpdateDivision(nullptr);
frame->m_div_rename->Enable(false);
+ frame->m_div_divregen->Enable(false);
frame->m_div_delete->Enable(false);
frame->m_div_smfout->Enable(false);
frame->m_div_divcopy->Enable(false);
@@ -130,6 +132,7 @@ void DivisionsView::DivisionChanged(){
editor->SetDivision(&div);
frame->UpdateDivision(&div);
frame->m_div_rename->Enable(true);
+ frame->m_div_divregen->Enable(true);
frame->m_div_delete->Enable(true);
frame->m_div_smfout->Enable(true);
frame->m_div_divcopy->Enable(true);
@@ -142,233 +145,166 @@ void DivisionsView::DivisionChanged(){
//======================================
+wxBEGIN_EVENT_TABLE(DivisionSettingDialog, wxDialog)
+ EVT_CHECKBOX(DivisionSettingDialog::ID_ScpyCheck, DivisionSettingDialog::OnScpyCheck)
+ EVT_COMMAND(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, DivisionSettingDialog::OnOK)
+wxEND_EVENT_TABLE()
-class DivisionSettingDialog : public wxDialog{
- enum{
- ID_NameLabel = 1,
- ID_NameInput = 2,
- ID_MidiBox = 30,
- ID_ScpyCheck = 29,
- ID_MhmgLabel = 32,
- ID_MhmgInput = 33,
- ID_MintLabel = 3,
- ID_MintInput = 4,
- ID_SortLabel = 5,
- ID_SortCombo = 6,
- ID_ThrsLabel = 20,
- ID_TgatLabel = 7,
- ID_TgatInput = 8,
- ID_TvelLabel = 9,
- ID_TvelInput = 10,
- ID_DefnBox = 31,
-// ID_DfzzLabel = 11,
- ID_DfzzCheck = 12,
- ID_DfmlCheck = 21,
- ID_DfstLabel = 13,
- ID_DfstInput = 14,
- ID_DfmtLabel = 22,
- ID_DfmtInput = 23
- };
- wxStaticText *name_label;
- wxTextCtrl *name_input;
- wxStaticBox *midi_box;
- wxCheckBox *scpy_check;
- wxStaticText *mhmg_label;
- wxTextCtrl *mhmg_input;
- wxStaticText *mint_label;
- wxTextCtrl *mint_input;
- wxStaticText *sort_label;
- wxComboBox *sort_combo;
- wxStaticText *thrs_label;
- wxStaticText *tgat_label;
- wxTextCtrl *tgat_input;
- wxStaticText *tvel_label;
- wxTextCtrl *tvel_input;
- wxStaticBox *defn_box;
-// wxStaticText *dfzz_label;
- wxCheckBox *dfzz_check;
- wxCheckBox *dfml_check;
- wxStaticText *dfst_label;
- wxTextCtrl *dfst_input;
- wxStaticText *dfmt_label;
- wxTextCtrl *dfmt_input;
- wxButton *button_ok, *button_cancel;
- int quantize;
- static const int _lm=15, _tm=5, _lw=25, _lb=30, _fc=150, _sc=130, _bw=5, _cw=25;
-public:
- DivisionSettingDialog(wxWindow *owner, DivisionSetting setting, int _quantize) :
- wxDialog(owner, -1, _("Division settings"), wxDefaultPosition, wxSize(_lm*2+_fc+_sc+_bw*2+10, _tm*2+_lw*15+_lb+_bw+_cw+10)), quantize(_quantize)
- {
- static wxString sort_choices[] = {
- _("None"),
- _("nn/gate/vel"),
- _("nn/vel/gate"),
- _("gate/nn/vel"),
- _("gate/vel/nn"),
- _("vel/nn/gate"),
- _("vel/gate/nn"),
- };
-
- auto spacing = 10;
- auto this_sizer = new wxBoxSizer(wxVERTICAL);
- auto main_flags = wxSizerFlags().Border(wxALL, 10).Expand();
-
- auto name_row = new wxBoxSizer(wxHORIZONTAL);
- name_label = new wxStaticText(this, ID_NameLabel, _("Name (&N):"));
- name_input = new wxTextCtrl(this, ID_NameInput, setting.name);
- name_row->Add(name_label);
- name_row->AddSpacer(spacing);
- name_row->Add(name_input, 1);
-
- this_sizer->Add(name_row, main_flags);
-
- auto settings_row = new wxStaticBoxSizer(wxVERTICAL, this, _("MIDI settings"));
- auto settings_row_flags = wxSizerFlags().Border(wxALL, spacing).Expand();
-
- scpy_check = new wxCheckBox(this, ID_ScpyCheck, _("Leave MIDI unaltered (&C)"));
- scpy_check->SetValue(setting.src_copy);
- settings_row->Add(scpy_check, settings_row_flags);
-
- auto midi_settings_sizer = new wxGridSizer(3, 2, 10, 10);
-
- mhmg_label = new wxStaticText(this, ID_MhmgLabel, _("Leading silence (&H):"));
- mhmg_input = new wxTextCtrl(this, ID_MhmgInput, wxString::Format(_("%f"), (double)setting.head_margin/quantize));
- mint_label = new wxStaticText(this, ID_MintLabel, _("Min. interval gap (&I):"));
- mint_input = new wxTextCtrl(this, ID_MintInput, wxString::Format(_("%f"), (double)setting.min_interval/quantize));
- sort_label = new wxStaticText(this, ID_SortLabel, _("Sorting method (&S):"));
- sort_combo = new wxComboBox(this, ID_SortCombo, sort_choices[(int)setting.sort_type], wxDefaultPosition, wxDefaultSize, 7, sort_choices, wxCB_DROPDOWN | wxCB_READONLY);
-
- midi_settings_sizer->Add(mhmg_label);
- midi_settings_sizer->Add(mhmg_input, wxSizerFlags().Expand());
- midi_settings_sizer->Add(mint_label);
- midi_settings_sizer->Add(mint_input, wxSizerFlags().Expand());
- midi_settings_sizer->Add(sort_label);
- midi_settings_sizer->Add(sort_combo, wxSizerFlags().Expand());
-
- settings_row->Add(midi_settings_sizer, settings_row_flags);
-
- auto min_difference_settings_sizer_outer = new wxStaticBoxSizer(wxVERTICAL, this, _("Minimum difference in:"));
- settings_row->Add(min_difference_settings_sizer_outer, wxSizerFlags().Expand());
-
- auto min_difference_settings_sizer = new wxGridSizer(2, 2, 10, 10);
- min_difference_settings_sizer_outer->Add(min_difference_settings_sizer, wxSizerFlags().Border(wxALL, spacing).Expand());
-
- tgat_label = new wxStaticText(this, ID_TgatLabel, _(" Length (&G):"));
- tgat_input = new wxTextCtrl(this, ID_TgatInput, wxString::Format(_("%f"), (double)setting.gate_threshold/quantize));
- tvel_label = new wxStaticText(this, ID_TvelLabel, _(" Velocity (&V):"));
- tvel_input = new wxTextCtrl(this, ID_TvelInput, wxString::Format(_("%zu"), setting.velocity_threshold));
- min_difference_settings_sizer->Add(tgat_label);
- min_difference_settings_sizer->Add(tgat_input, wxSizerFlags().Expand());
- min_difference_settings_sizer->Add(tvel_label);
- min_difference_settings_sizer->Add(tvel_input, wxSizerFlags().Expand());
-
- this_sizer->Add(settings_row, main_flags);
-
- auto def_settings_sizer_outer = new wxStaticBoxSizer(wxVERTICAL, this, _("Definition settings"));
- this_sizer->Add(def_settings_sizer_outer, main_flags);
-
- auto def_settings_sizer = new wxGridSizer(3, 2, 15, 15);
- def_settings_sizer_outer->Add(def_settings_sizer, wxSizerFlags().Border(wxALL, spacing));
+DivisionSettingDialog::DivisionSettingDialog(wxWindow *owner, DivisionSetting setting, int _quantize) :
+ wxDialog(owner, -1, _("Division settings"), wxDefaultPosition, wxSize(_lm*2+_fc+_sc+_bw*2+10, _tm*2+_lw*15+_lb+_bw+_cw+10)), quantize(_quantize)
+{
+ static wxString sort_choices[] = {
+ _("None"),
+ _("nn/gate/vel"),
+ _("nn/vel/gate"),
+ _("gate/nn/vel"),
+ _("gate/vel/nn"),
+ _("vel/nn/gate"),
+ _("vel/gate/nn"),
+ };
+
+ auto spacing = 10;
+ auto this_sizer = new wxBoxSizer(wxVERTICAL);
+ auto main_flags = wxSizerFlags().Border(wxALL, 10).Expand();
+
+ auto name_row = new wxBoxSizer(wxHORIZONTAL);
+ name_label = new wxStaticText(this, ID_NameLabel, _("Name (&N):"));
+ name_input = new wxTextCtrl(this, ID_NameInput, setting.name);
+ name_row->Add(name_label);
+ name_row->AddSpacer(spacing);
+ name_row->Add(name_input, 1);
+
+ this_sizer->Add(name_row, main_flags);
+
+ auto settings_row = new wxStaticBoxSizer(wxVERTICAL, this, _("MIDI settings"));
+ auto settings_row_flags = wxSizerFlags().Border(wxALL, spacing).Expand();
+
+ scpy_check = new wxCheckBox(this, ID_ScpyCheck, _("Leave MIDI unaltered (&C)"));
+ scpy_check->SetValue(setting.src_copy);
+ settings_row->Add(scpy_check, settings_row_flags);
+
+ auto midi_settings_sizer = new wxGridSizer(3, 2, 10, 10);
+
+ mhmg_label = new wxStaticText(this, ID_MhmgLabel, _("Leading silence (&H):"));
+ mhmg_input = new wxTextCtrl(this, ID_MhmgInput, wxString::Format(_("%f"), (double)setting.head_margin/quantize));
+ mint_label = new wxStaticText(this, ID_MintLabel, _("Min. interval gap (&I):"));
+ mint_input = new wxTextCtrl(this, ID_MintInput, wxString::Format(_("%f"), (double)setting.min_interval/quantize));
+ sort_label = new wxStaticText(this, ID_SortLabel, _("Sorting method (&S):"));
+ sort_combo = new wxComboBox(this, ID_SortCombo, sort_choices[(int)setting.sort_type], wxDefaultPosition, wxDefaultSize, 7, sort_choices, wxCB_DROPDOWN | wxCB_READONLY);
+
+ midi_settings_sizer->Add(mhmg_label);
+ midi_settings_sizer->Add(mhmg_input, wxSizerFlags().Expand());
+ midi_settings_sizer->Add(mint_label);
+ midi_settings_sizer->Add(mint_input, wxSizerFlags().Expand());
+ midi_settings_sizer->Add(sort_label);
+ midi_settings_sizer->Add(sort_combo, wxSizerFlags().Expand());
+
+ settings_row->Add(midi_settings_sizer, settings_row_flags);
+
+ auto min_difference_settings_sizer_outer = new wxStaticBoxSizer(wxVERTICAL, this, _("Minimum difference in:"));
+ settings_row->Add(min_difference_settings_sizer_outer, wxSizerFlags().Expand());
+
+ auto min_difference_settings_sizer = new wxGridSizer(2, 2, 10, 10);
+ min_difference_settings_sizer_outer->Add(min_difference_settings_sizer, wxSizerFlags().Border(wxALL, spacing).Expand());
+
+ tgat_label = new wxStaticText(this, ID_TgatLabel, _(" Length (&G):"));
+ tgat_input = new wxTextCtrl(this, ID_TgatInput, wxString::Format(_("%f"), (double)setting.gate_threshold/quantize));
+ tvel_label = new wxStaticText(this, ID_TvelLabel, _(" Velocity (&V):"));
+ tvel_input = new wxTextCtrl(this, ID_TvelInput, wxString::Format(_("%zu"), setting.velocity_threshold));
+ min_difference_settings_sizer->Add(tgat_label);
+ min_difference_settings_sizer->Add(tgat_input, wxSizerFlags().Expand());
+ min_difference_settings_sizer->Add(tvel_label);
+ min_difference_settings_sizer->Add(tvel_input, wxSizerFlags().Expand());
+
+ this_sizer->Add(settings_row, main_flags);
+
+ auto def_settings_sizer_outer = new wxStaticBoxSizer(wxVERTICAL, this, _("Definition settings"));
+ this_sizer->Add(def_settings_sizer_outer, main_flags);
+
+ auto def_settings_sizer = new wxGridSizer(3, 2, 15, 15);
+ def_settings_sizer_outer->Add(def_settings_sizer, wxSizerFlags().Border(wxALL, spacing));
// dfzz_label = new wxStaticText(this, ID_DfzzLabel, _("ZZ定義を有効にする(&Z):"), wxPoint(_lm,_tm+_lw*11+3), wxSize(_fc,15));
- dfzz_check = new wxCheckBox(this, ID_DfzzCheck, _("Use base-36 range(00-ZZ) (&Z)")); dfzz_check->SetValue(setting.zz_definition);
- dfml_check = new wxCheckBox(this, ID_DfmlCheck, _("Use overloading (&M)")); dfml_check->SetValue(setting.ml_definition);
- dfst_label = new wxStaticText(this, ID_DfstLabel, _("Starting BMS Index (&D):"));
- dfst_input = new wxTextCtrl(this, ID_DfstInput, setting.start_definition.to_string());
- dfmt_label = new wxStaticText(this, ID_DfmtLabel, _("Overloading Interval (&L):"));
- dfmt_input = new wxTextCtrl(this, ID_DfmtInput, wxString::Format(_("%f"), (double)setting.ml_threshold/quantize));
-
- def_settings_sizer->Add(dfzz_check);
- def_settings_sizer->Add(dfml_check);
- def_settings_sizer->Add(dfst_label);
- def_settings_sizer->Add(dfst_input, wxSizerFlags().Expand());
- def_settings_sizer->Add(dfmt_label);
- def_settings_sizer->Add(dfmt_input, wxSizerFlags().Expand());
-
-
- auto dialog_bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
- this_sizer->Add(dialog_bottom_sizer, wxSizerFlags().Align(wxALIGN_RIGHT).Border(wxALL));
-
- button_ok = new wxButton(this, wxID_OK, _("OK"));
- button_cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
- dialog_bottom_sizer->Add(button_ok);
- dialog_bottom_sizer->Add(button_cancel);
-
- SetSizerAndFit(this_sizer);
- button_ok->SetDefault();
- SetEscapeId(wxID_CANCEL);
- }
- void GetSetting(DivisionSetting &setting){
- double db;
- long lb;
- setting.name = name_input->GetValue();
- setting.src_copy = scpy_check->GetValue();
- if (mhmg_input->GetValue().ToDouble(&db)) setting.head_margin = (int)(db*quantize);
- if (mint_input->GetValue().ToDouble(&db)) setting.min_interval = (int)(db*quantize);
- setting.sort_type = (DivisionSetting::SortType)sort_combo->GetSelection();
- if (tgat_input->GetValue().ToDouble(&db)) setting.gate_threshold = (int)(db*quantize);
- if (tvel_input->GetValue().ToLong(&lb)) setting.velocity_threshold = lb;
- setting.zz_definition = dfzz_check->GetValue();
- setting.ml_definition = dfml_check->GetValue();
- setting.start_definition.from_string(dfst_input->GetValue());
- if (dfmt_input->GetValue().ToDouble(&db)) setting.ml_threshold = (int)(db*quantize);
- }
- void OnScpyCheck(wxCommandEvent &WXUNUSED(ev)){
- bool enabled = !scpy_check->GetValue();
- mint_input->Enable(enabled);
- sort_combo->Enable(enabled);
- tgat_input->Enable(enabled);
- tvel_input->Enable(enabled);
- }
- void OnOK(wxCommandEvent &WXUNUSED(ev)){
- wxString s = dfst_input->GetValue();
- ZZNumber zz;
- bool zz_enabled = dfzz_check->GetValue();
- if (s.length() != 2 || !zz.from_string(s) || (!zz_enabled && !zz.in_ff())){
- MessageBeep(0); // windows
- return;
- }
- this->EndDialog(wxID_OK);
- }
- wxDECLARE_EVENT_TABLE();
-};
+ dfzz_check = new wxCheckBox(this, ID_DfzzCheck, _("Use base-36 range(00-ZZ) (&Z)")); dfzz_check->SetValue(setting.zz_definition);
+ dfml_check = new wxCheckBox(this, ID_DfmlCheck, _("Use overloading (&M)")); dfml_check->SetValue(setting.ml_definition);
+ dfst_label = new wxStaticText(this, ID_DfstLabel, _("Starting BMS Index (&D):"));
+ dfst_input = new wxTextCtrl(this, ID_DfstInput, setting.start_definition.to_string());
+ dfmt_label = new wxStaticText(this, ID_DfmtLabel, _("Overloading Interval (&L):"));
+ dfmt_input = new wxTextCtrl(this, ID_DfmtInput, wxString::Format(_("%f"), (double)setting.ml_threshold/quantize));
+
+ def_settings_sizer->Add(dfzz_check);
+ def_settings_sizer->Add(dfml_check);
+ def_settings_sizer->Add(dfst_label);
+ def_settings_sizer->Add(dfst_input, wxSizerFlags().Expand());
+ def_settings_sizer->Add(dfmt_label);
+ def_settings_sizer->Add(dfmt_input, wxSizerFlags().Expand());
+
+
+ auto dialog_bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
+ this_sizer->Add(dialog_bottom_sizer, wxSizerFlags().Align(wxALIGN_RIGHT).Border(wxALL));
+
+ button_ok = new wxButton(this, wxID_OK, _("OK"));
+ button_cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));
+ dialog_bottom_sizer->Add(button_ok);
+ dialog_bottom_sizer->Add(button_cancel);
+
+ SetSizerAndFit(this_sizer);
+ button_ok->SetDefault();
+ SetEscapeId(wxID_CANCEL);
+}
+void DivisionSettingDialog::GetSetting(DivisionSetting &setting) {
+ double db;
+ long lb;
+ setting.name = name_input->GetValue();
+ setting.src_copy = scpy_check->GetValue();
+ if (mhmg_input->GetValue().ToDouble(&db)) setting.head_margin = (int)(db*quantize);
+ if (mint_input->GetValue().ToDouble(&db)) setting.min_interval = (int)(db*quantize);
+ setting.sort_type = (DivisionSetting::SortType)sort_combo->GetSelection();
+ if (tgat_input->GetValue().ToDouble(&db)) setting.gate_threshold = (int)(db*quantize);
+ if (tvel_input->GetValue().ToLong(&lb)) setting.velocity_threshold = lb;
+ setting.zz_definition = dfzz_check->GetValue();
+ setting.ml_definition = dfml_check->GetValue();
+ setting.start_definition.from_string(dfst_input->GetValue());
+ if (dfmt_input->GetValue().ToDouble(&db)) setting.ml_threshold = (int)(db*quantize);
+}
-wxBEGIN_EVENT_TABLE(DivisionSettingDialog, wxDialog)
- EVT_CHECKBOX(DivisionSettingDialog::ID_ScpyCheck, DivisionSettingDialog::OnScpyCheck)
- EVT_COMMAND(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, DivisionSettingDialog::OnOK)
-wxEND_EVENT_TABLE()
+void DivisionSettingDialog::OnScpyCheck(wxCommandEvent &) {
+ bool enabled = !scpy_check->GetValue();
+ mint_input->Enable(enabled);
+ sort_combo->Enable(enabled);
+ tgat_input->Enable(enabled);
+ tvel_input->Enable(enabled);
+}
+void DivisionSettingDialog::OnOK(wxCommandEvent &) {
+ wxString s = dfst_input->GetValue();
+ ZZNumber zz;
+ bool zz_enabled = dfzz_check->GetValue();
+ if (s.length() != 2 || !zz.from_string(s) || (!zz_enabled && !zz.in_ff())){
+ MessageBeep(0); // windows
+ return;
+ }
+ this->EndDialog(wxID_OK);
+}
void DivisionsView::_NewDivision(){
if (!frame->project) return;
int quantize = frame->project->GetSource().get_quantize();
- DivisionSetting setting;
wxFileName fn(frame->project->GetSource().source_filename);
auto fn_no_ext = fn.GetName();
- setting.name = fn_no_ext;
- setting.src_copy = false;
- setting.head_margin = 0;
- setting.min_interval = quantize*1;
- setting.sort_type = DivisionSetting::SORT_NN_GATE_V;
- setting.gate_threshold = quantize/8;
- setting.velocity_threshold = 5;
- setting.zz_definition = true;
- setting.ml_definition = true;
- setting.start_definition = 1;
- setting.ml_threshold = quantize/2;
- DivisionSettingDialog *dialog = new DivisionSettingDialog(frame, setting, quantize);
- int ret = dialog->ShowModal();
+ DivisionSetting setting(fn_no_ext, quantize);
+
+ DivisionSettingDialog dialog (frame, setting, quantize);
+ int ret = dialog.ShowModal();
if (ret != wxID_OK){
- dialog->Destroy();
return;
}
- dialog->GetSetting(setting);
- dialog->Destroy();
- size_t i = frame->project->CreateDivision(setting);
+ dialog.GetSetting(setting);
+ frame->project->CreateDivision(setting);
divisions->SetSelection(divisions->Append(setting.name));
DivisionChanged();
}
@@ -389,6 +325,13 @@ void DivisionsView::OnDivRename(wxMenuEvent &event) {
}
}
+void DivisionsView::OnDivRegenerate(wxMenuEvent &event) {
+ if (editor->OnDivRegenerate(event)) {
+ frame->project->SetChangeFlag();
+ DivisionChanged();
+ }
+}
+
diff --git a/src/divview.h b/src/divview.h
index dc67c41..4416a11 100644
--- a/src/divview.h
+++ b/src/divview.h
@@ -46,6 +46,7 @@ class DivisionEditor : public wxWindow{
void OnSeqCopy(wxCommandEvent &event){ _SeqCopy(); }
void OnSmfOut(wxMenuEvent &event){ _SmfOut(); }
void OnDivCopy(wxMenuEvent &event){ _DivCopy(); }
+ bool OnDivRegenerate(wxMenuEvent &event);
void OnDefOut(wxMenuEvent &event){ DefOut(); }
bool OnDivRename(wxMenuEvent &event) { return DivRename(); }
void OnSeqCopy(wxMenuEvent &event){ _SeqCopy(); }
@@ -83,6 +84,7 @@ class DivisionsView : public wxWindow{
void OnNewDivision(wxMenuEvent &event);
void OnDeleteDivision(wxMenuEvent &event);
void OnDivRename(wxMenuEvent &event);
+ void OnDivRegenerate(wxMenuEvent &event);
void OnSelectDivision(wxCommandEvent &event);
void ProjectChanged();
void DivisionChanged();
diff --git a/src/frame.cpp b/src/frame.cpp
index 9a86290..2abeb26 100644
--- a/src/frame.cpp
+++ b/src/frame.cpp
@@ -20,6 +20,7 @@ enum {
ID_DivDefOut = 0x0205,
ID_DivSeqCopy = 0x0206,
ID_DivRename = 0x0207,
+ ID_DivDivRegen = 0x208,
ID_Help = 0x0901,
ID_About = 0x0903
};
@@ -42,7 +43,7 @@ wxEND_EVENT_TABLE()
FrameWindow::FrameWindow(const wxPoint &pos, const wxSize &size)
-: wxFrame(NULL, -1, app_name, pos, size),
+: wxFrame(nullptr, -1, app_name, pos, size),
menu_bar(new wxMenuBar), status_bar(CreateStatusBar()),
m_file(new wxMenu), m_div(new wxMenu), m_help(new wxMenu),
m_file_new(new wxMenuItem(m_file, ID_New, _("New project (&N)...\tCtrl+N"))),
@@ -56,26 +57,29 @@ m_div_rename(new wxMenuItem(m_div, ID_DivRename, _("Rename division (&R)...\tF2"
m_div_delete(new wxMenuItem(m_div, ID_DivDelete, _("Delete division (&D)"))),
m_div_smfout(new wxMenuItem(m_div, ID_DivSmfOut, _("Write modified MIDI File (&M)..."))),
m_div_divcopy(new wxMenuItem(m_div, ID_DivDivCopy, _("Copy division (&W)"))),
+m_div_divregen(new wxMenuItem(m_div, ID_DivDivRegen, _("Regenerate division (&E)...\tCtrl+R"))),
m_div_defout(new wxMenuItem(m_div, ID_DivDefOut, _("Definition information (&D)..."))),
m_div_seqcopy(new wxMenuItem(m_div, ID_DivSeqCopy, _("Copy BMS sequence to clipboard (&S)"))),
m_help_help(new wxMenuItem(m_help, ID_Help, _("Help (&H)...\tF1"))),
m_help_about(new wxMenuItem(m_help, ID_About, _("About (&I)..."))),
-splitter(0), src(0), div(0),
-project(0)
+splitter(nullptr), src(nullptr), div(nullptr),
+project(nullptr)
{
// init gui
wxIcon ico("BMHICON", wxBITMAP_TYPE_ICO_RESOURCE);
SetIcon(ico);
- wxAcceleratorEntry acs[7];
+ wxAcceleratorEntry acs[9];
acs[0].Set(wxACCEL_CTRL, (int)'N', ID_New);
acs[1].Set(wxACCEL_CTRL, (int)'O', ID_Open);
acs[2].Set(wxACCEL_CTRL, (int)'S', ID_Save);
acs[3].Set(wxACCEL_CTRL | wxACCEL_SHIFT, (int)'S', ID_SaveAs);
acs[4].Set(wxACCEL_CTRL, (int)'Q', ID_Quit);
acs[5].Set(wxACCEL_NORMAL, WXK_F5, ID_DivNew);
- acs[6].Set(wxACCEL_NORMAL, WXK_F2, ID_Help);
- wxAcceleratorTable accel(7, acs);
+ acs[6].Set(wxACCEL_NORMAL, WXK_F1, ID_Help);
+ acs[7].Set(wxACCEL_NORMAL, WXK_F2, ID_DivRename);
+ acs[8].Set(wxACCEL_CTRL, (int)'R', ID_DivDivRegen);
+ wxAcceleratorTable accel(9, acs);
SetAcceleratorTable(accel);
m_file->Append(m_file_new);
@@ -86,8 +90,10 @@ project(0)
m_file->AppendSeparator();
m_file->Append(m_file_quit);
menu_bar->Append(m_file, _("File (&F)"));
+
m_div->Append(m_div_new);
m_div->Append(m_div_rename);
+ m_div->Append(m_div_divregen);
m_div->Append(m_div_delete);
m_div->AppendSeparator();
m_div->Append(m_div_smfout);
@@ -95,9 +101,11 @@ project(0)
m_div->Append(m_div_defout);
m_div->Append(m_div_seqcopy);
menu_bar->Append(m_div, _("Divisions (&D)"));
+
m_help->Append(m_help_help);
m_help->Append(m_help_about);
menu_bar->Append(m_help, _("Help (&H)"));
+
SetMenuBar(menu_bar);
status_bar->SetFieldsCount(3);
@@ -115,6 +123,7 @@ project(0)
Connect(ID_DivDelete, wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler(DivisionsView::OnDeleteDivision), 0, div);
Connect(ID_DivSmfOut, wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler(DivisionEditor::OnSmfOut), 0, div->editor);
Connect(ID_DivDivCopy, wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler(DivisionEditor::OnDivCopy), 0, div->editor);
+ Connect(ID_DivDivRegen, wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler(DivisionsView::OnDivRegenerate), 0, div);
Connect(ID_DivDefOut, wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler(DivisionEditor::OnDefOut), 0, div->editor);
Connect(ID_DivSeqCopy, wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler(DivisionEditor::OnSeqCopy), 0, div->editor);
Connect(ID_DivRename, wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler(DivisionsView::OnDivRename), 0, div);
@@ -123,7 +132,7 @@ project(0)
}
FrameWindow::~FrameWindow(){
- SetProject(0);
+ SetProject(nullptr);
}
void FrameWindow::OpenFiles(int nFiles, std::vector FileNames){
diff --git a/src/frame.h b/src/frame.h
index 0d2083d..ee38635 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -19,7 +19,17 @@ class FrameWindow : public wxFrame, public ProjectObserver{
wxStatusBar *status_bar;
wxMenu *m_file, *m_div, *m_help;
wxMenuItem *m_file_new, *m_file_open, *m_file_save, *m_file_save_as, *m_file_close, *m_file_quit;
- wxMenuItem *m_div_new, *m_div_delete, *m_div_smfout, *m_div_divcopy, *m_div_defout, *m_div_seqcopy, *m_div_rename;
+
+ wxMenuItem
+ *m_div_new,
+ *m_div_delete,
+ *m_div_smfout,
+ *m_div_divcopy,
+ *m_div_divregen,
+ *m_div_defout,
+ *m_div_seqcopy,
+ *m_div_rename;
+
wxMenuItem *m_help_help, *m_help_about;
wxSplitterWindow *splitter;
SourceView *src;
diff --git a/src/midi_sr.cpp b/src/midi_sr.cpp
index 0c9e04d..4a9bc38 100644
--- a/src/midi_sr.cpp
+++ b/src/midi_sr.cpp
@@ -8,66 +8,66 @@ static const NodeName _note_ = StringToNodeName("note");
static const NodeName _ptch_ = StringToNodeName("ptch");
static const NodeName _cchg_ = StringToNodeName("ccgh");
-struct _MidiCCEvent : public MidiParamEvent{
- int cc_num;
+struct _MidiCCEvent : public MidiParamEvent {
+ int cc_num;
};
-bool MidiData::read_tree(TreeNode &node){
- init();
- for (auto & sub : node){
- if (sub.get_name() == _qntz_){
- if (sub.get_data_size() == sizeof(int)) sub.get_data(&quantize, sizeof(int));
- }else if (sub.get_name() == _note_){
- MidiNoteEvent e;
- if (sub.get_data_size() == sizeof(MidiNoteEvent)){
- sub.get_data(&e, sizeof(MidiNoteEvent));
- note_events.push_back(e);
- }
- }else if (sub.get_name() == _ptch_){
- MidiParamEvent e;
- if (sub.get_data_size() == sizeof(MidiParamEvent)){
- sub.get_data(&e, sizeof(MidiParamEvent));
- pb_events.push_back(e);
- }
- }else if (sub.get_name() == _cchg_){
- _MidiCCEvent e;
- if (sub.get_data_size() == sizeof(_MidiCCEvent)){
- sub.get_data(&e, sizeof(_MidiCCEvent));
- auto i = cc_lanes.find(e.cc_num);
- if (i == cc_lanes.end()){
- std::pair< MidiCCLanesMap::iterator, bool > x;
- x = cc_lanes.insert(MidiCCLanePair(e.cc_num, MidiParamsLane()));
- i = x.first;
- }
- i->second.push_back(*static_cast(&e));
- }
- }
- }
- return true;
+bool MidiData::read_tree(TreeNode &node) {
+ init();
+ for (auto &sub : node) {
+ if (sub.get_name() == _qntz_) {
+ if (sub.get_data_size() == sizeof(int)) sub.get_data(&quantize, sizeof(int));
+ } else if (sub.get_name() == _note_) {
+ MidiNoteEvent e;
+ if (sub.get_data_size() == sizeof(MidiNoteEvent)) {
+ sub.get_data(&e, sizeof(MidiNoteEvent));
+ note_events.push_back(e);
+ }
+ } else if (sub.get_name() == _ptch_) {
+ MidiParamEvent e;
+ if (sub.get_data_size() == sizeof(MidiParamEvent)) {
+ sub.get_data(&e, sizeof(MidiParamEvent));
+ pb_events.push_back(e);
+ }
+ } else if (sub.get_name() == _cchg_) {
+ _MidiCCEvent e;
+ if (sub.get_data_size() == sizeof(_MidiCCEvent)) {
+ sub.get_data(&e, sizeof(_MidiCCEvent));
+ auto i = cc_lanes.find(e.cc_num);
+ if (i == cc_lanes.end()) {
+ std::pair x;
+ x = cc_lanes.insert(MidiCCLanePair(e.cc_num, MidiParamsLane()));
+ i = x.first;
+ }
+ i->second.push_back(*static_cast(&e));
+ }
+ }
+ }
+ return true;
}
-bool MidiData::write_tree(TreeNode &node){
- node.push_back(_qntz_);
- node.back().set_data(&quantize, sizeof(int));
- for (auto & note_event : note_events){
- node.push_back(_note_);
- node.back().set_data(¬e_event, sizeof(MidiNoteEvent));
- }
- for (MidiParamsLane::iterator i=pb_events.begin(); i!=pb_events.end(); i++){
- node.push_back(_ptch_);
- node.back().set_data(&(*i), sizeof(MidiParamEvent));
- }
- for (MidiCCLanesMap::iterator lane=cc_lanes.begin(); lane!=cc_lanes.end(); lane++){
- for (MidiParamsLane::iterator i=lane->second.begin(); i!=lane->second.end(); i++){
- _MidiCCEvent e;
- e.position = i->position;
- e.value = i->value;
- e.cc_num = lane->first;
- node.push_back(_cchg_);
- node.back().set_data(&e, sizeof(_MidiCCEvent));
- }
- }
- return true;
+bool MidiData::write_tree(TreeNode &node) {
+ node.push_back(_qntz_);
+ node.back().set_data(&quantize, sizeof(int));
+ for (auto ¬e_event : note_events) {
+ node.push_back(_note_);
+ node.back().set_data(¬e_event, sizeof(MidiNoteEvent));
+ }
+ for (auto & pb_event : pb_events) {
+ node.push_back(_ptch_);
+ node.back().set_data(&pb_event, sizeof(MidiParamEvent));
+ }
+ for (auto &cc_lane : cc_lanes) {
+ for (auto i = cc_lane.second.begin(); i != cc_lane.second.end(); i++) {
+ _MidiCCEvent e;
+ e.position = i->position;
+ e.value = i->value;
+ e.cc_num = cc_lane.first;
+ node.push_back(_cchg_);
+ node.back().set_data(&e, sizeof(_MidiCCEvent));
+ }
+ }
+ return true;
}
diff --git a/src/serialize.h b/src/serialize.h
index 749fd08..eb3052b 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -5,10 +5,10 @@
#include "common.h"
#include
-// f[^̊ȈՐK
-// قRIFFƓKw^`NVXeBgGfBAB
-// RIFFłƂRIFF/LIST`N͑啶pŎn܂`N(m[h)ŕ\BȊO͒ʏ`N
-// ẻɓm[h̃m[hĂ悢
+// データの簡易尻洗い座
+// ほぼRIFFと同じ階層型チャンクシステム。リトルエンディアン。
+// RIFFでいうところのRIFF/LISTチャンクは大文字英数で始まるチャンク名(ノード名)で表す。それ以外は通常チャンク
+// 同じ親の下に同じノード名のノードが複数あってもよい
typedef unsigned long NodeName;
@@ -63,7 +63,7 @@ class TreeNode : public std::vector{
NodeSizeType size;
file.Read(&size, sizeof(NodeSizeType));
if (is_list()){
- // XgñAȂqvfǂݍ
+ // リスト系のアレなら子要素を読み込む
wxFileOffset inner_head = file.Tell();
wxFileOffset inner_tail = inner_head + size;
while (file.Tell() < inner_tail){
@@ -72,7 +72,7 @@ class TreeNode : public std::vector{
}
file.Seek(inner_tail);
}else{
- // XgłȂΎdataɓǂݍ
+ // リストでなければ自分のdataに読み込む
if (size){
data = new char[data_size = size];
file.Read(data, data_size);
@@ -84,8 +84,8 @@ class TreeNode : public std::vector{
if (is_list()){
file.Seek(sizeof(NodeSizeType), wxFromCurrent);
wxFileOffset inner_head = file.Tell();
- for (std::vector::const_iterator i=begin(); i!=end(); i++){
- i->write(file);
+ for (const auto & i : *this){
+ i.write(file);
}
wxFileOffset inner_tail = file.Tell();
NodeSizeType size = inner_tail - inner_head;