Skip to content

Commit

Permalink
Feature: 量化导出
Browse files Browse the repository at this point in the history
  • Loading branch information
Vescrity committed May 16, 2024
1 parent 9afe764 commit 463ada8
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 38 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- [x] BPM 推断
- [x] midi 导出
- [x] 区段筛选编辑
- [ ] 量化后导出
- [x] 量化导出
- [ ] 自定义配置
- [ ] 命令批处理

Expand Down
6 changes: 3 additions & 3 deletions workspace/Midi_Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ void Midi_Writer::open(const string &filename)
}
void Midi_Writer::set_bpm(const long double &bpm)
{
microsec_per_beat = 60000000ul / bpm;
uint32_t microsec_per_beat = 60000000ul / bpm;
tick_time = microsec_per_beat / TPQN;
// TODO: 写入文件
outfile.write("MTrk", 4);
writer.append(0);
Expand Down Expand Up @@ -56,7 +57,7 @@ void Midi_Writer::close()
}
Midi_Writer::Midi_Writer()
{
TPQN = 120;
TPQN = 0xF0;
numerator = 4;
power2 = 2;
}
Expand All @@ -78,7 +79,6 @@ std::vector<unsigned char> VLQ_encode(unsigned long ticks)

uint32_t Midi_Writer::msec2tick(const uint32_t &msec)
{
auto tick_time = microsec_per_beat / TPQN;
return msec * 1000 / tick_time;
}

Expand Down
3 changes: 2 additions & 1 deletion workspace/Midi_Writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class Midi_Writer
uint8_t TPQN;
uint8_t numerator;
uint8_t power2;
uint32_t microsec_per_beat;
uint tick_time;
// uint32_t microsec_per_beat;
std::ofstream outfile;
Binary_Writer writer;

Expand Down
17 changes: 13 additions & 4 deletions workspace/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <math.h>
using namespace std;

void NoteList::key_log(const string &s, const ull &t) { push_back(NoteEvent(s, t)); }
void NoteList::key_log(const string &s, const uint32_t &t) { push_back(NoteEvent(s, t)); }

void NoteList::show() const
{
Expand All @@ -25,19 +25,28 @@ void NoteList::clear()
dtime_ready = nindex_ready = bpm_ready = 0;
bpm = 0;
}
void NoteList::save_midi(const string &filename, uint8_t numerator, uint8_t power2) const
void NoteList::save_midi(const string &filename, uint8_t numerator, uint8_t power2, bool quan, int8_t qp2) const
{
Midi_Writer writer;
writer.open(filename);
writer.set_signature(numerator, power2);
writer.set_bpm(get_bpm());
auto n = list.size();
long double _time = 240000.0 / get_bpm() / (1 << qp2);
calc_dtime();
for (int i = 0; i < n - 1; i++)
{
writer.addnote(list[i].get_number(), writer.msec2tick(dtime[i]));
auto ti = dtime[i];
if (quan)
{
ti = round(ti / _time);
if (ti < 1)
ti = 1;
ti *= _time;
}
writer.addnote(list[i].get_number(), writer.msec2tick(ti));
}
writer.addnote(list[n - 1].get_number(), 120);
writer.addnote(list[n - 1].get_number(), 0xF0);
writer.close();
}

Expand Down
14 changes: 7 additions & 7 deletions workspace/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ class NoteEvent
short sharp_flat;
// prefix,octave = 6,0 -> 440Hz
short octave;
ull time;
uint32_t time;
friend class NoteList;

public:
NoteEvent(const string &str, const ull &t)
NoteEvent(const string &str, const uint32_t &t)
: prefix(str), time(t), sharp_flat(0), octave(0){};
void show() const;
string html() const;
Expand All @@ -25,11 +25,11 @@ class NoteList
{
vector<NoteEvent> list;
mutable bool dtime_ready;
mutable vector<ull> dtime;
mutable vector<uint32_t> dtime;
mutable bool nindex_ready;
mutable vector<unsigned> nindex;
void calc_nindex() const;
ull time_try() const;
uint32_t time_try() const;
void calc_dtime() const;
mutable bool bpm_ready;
mutable double bpm;
Expand All @@ -41,7 +41,7 @@ class NoteList
bpm = -1;
nindex_ready = dtime_ready = bpm_ready = 0;
}
void save_midi(const string &filename, uint8_t numerator, uint8_t power2) const;
void save_midi(const string &filename, uint8_t numerator, uint8_t power2, bool quantize = 0, int8_t qp2 = 4) const;
std::string html() const;
std::vector<unsigned> get_nindex() const;
void push_back(const NoteEvent &e) { list.push_back(e); }
Expand All @@ -53,8 +53,8 @@ class NoteList
nindex.clear();
bpm = b;
};
void key_log(const string &s, const ull &t);
void operate(const unsigned &st,const unsigned &ed,const string &pattern,const string &oper);
void key_log(const string &s, const uint32_t &t);
void operate(const unsigned &st, const unsigned &ed, const string &pattern, const string &oper);
void show() const;
void clear();
};
15 changes: 7 additions & 8 deletions workspace/core_algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ void NoteList::calc_nindex() const
nindex.push_back(1);
for (int i = 1; i <= n; i++)
{
ull len = round(dtime[i - 1] * 1.0 / _16time);
dout << len << "\n";
uint32_t len = round(dtime[i - 1] * 1.0 / _16time);
nindex.push_back((len >= 2 ? len : 1) + 2 + nindex[i - 1]);
}

Expand All @@ -35,14 +34,14 @@ void NoteList::calc_dtime() const
}
dtime_ready = 1;
}
double time2bpm(const ull &t, int as = 16)
double time2bpm(const uint32_t &t, int as = 16)
{
return 240000.0 / t / as;
}
ull TIME_1 = 10;
ull TIME_2 = 25;
ull TIME_3 = 50;
ull NoteList::time_try() const
uint32_t TIME_1 = 10;
uint32_t TIME_2 = 25;
uint32_t TIME_3 = 50;
uint32_t NoteList::time_try() const
{
calc_dtime();
auto stime = dtime;
Expand Down Expand Up @@ -114,7 +113,7 @@ ull NoteList::time_try() const
}
if (q_size() < 5)
return 0;
ull sum = 0;
uint32_t sum = 0;
for (int i = head; i < tail; i++)
{
sum += stime[i];
Expand Down
18 changes: 12 additions & 6 deletions workspace/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ void Editor::editor_update()
}
void Editor::on_actionMidi_triggered()
{
QString fname = QFileDialog::getSaveFileName(this, tr("保存文件"), QDir::currentPath(), tr("MIDI 文件(*.mid)"));
QString fname = QFileDialog::getSaveFileName(
this, tr("保存文件"),
QDir::currentPath(),
tr("MIDI 文件(*.mid)"));
if (!fname.isEmpty())
{
current_list.save_midi(fname.toStdString(), numerator, power2);
current_list.save_midi(
fname.toStdString(), numerator, power2,
ui->quantizeCheckBox->isChecked(),
ui->quantizeComboBox->currentIndex() + 2);
ui->statusBar->showMessage(tr("文件已导出"));
}
else
Expand All @@ -47,7 +53,10 @@ void Editor::on_actionMidi_triggered()

void Editor::on_actionText_triggered()
{
QString fname = QFileDialog::getSaveFileName(this, tr("保存文件"), QDir::currentPath(), tr("HTML 文件(*.htm)"));
QString fname = QFileDialog::getSaveFileName(
this, tr("保存文件"),
QDir::currentPath(),
tr("HTML 文件(*.htm)"));
if (!fname.isEmpty())
{
auto s = ui->editorBrowser->toHtml();
Expand Down Expand Up @@ -121,6 +130,3 @@ void Editor::on_x2Button_clicked()
current_list.set_bpm(ui->bpmSpinBox->value() * 2.0);
editor_update();
}



92 changes: 84 additions & 8 deletions workspace/editor.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>401</width>
<height>354</height>
<width>430</width>
<height>435</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -134,7 +134,7 @@
</item>
</layout>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QTextBrowser" name="editorBrowser">
<property name="font">
<font>
Expand All @@ -143,7 +143,7 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;音符筛选规则。&lt;br/&gt;例如输入 367 会筛选选中范围中的 3 6 7&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
Expand All @@ -153,10 +153,10 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QLineEdit" name="patternEdit"/>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_4">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;对筛选的内容执行的操作&lt;br/&gt;升/降/还原: # b 0&lt;br/&gt;提升/降低八度: + -&lt;br/&gt;替换: r[替换后的音符]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
Expand All @@ -166,9 +166,73 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QLineEdit" name="commandEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;辅助功能,仅对单个音符长度进行量化。可能存在误差,仍需在 DAW 中进一步处理。&lt;/p&gt;&lt;p&gt;仅在导出 Midi 时生效&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>量化: </string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="quantizeCheckBox">
<property name="text">
<string>启用</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>对齐至: </string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="quantizeComboBox">
<property name="currentIndex">
<number>2</number>
</property>
<item>
<property name="text">
<string>1/4</string>
</property>
</item>
<item>
<property name="text">
<string>1/8</string>
</property>
</item>
<item>
<property name="text">
<string>1/16</string>
</property>
</item>
<item>
<property name="text">
<string>1/32</string>
</property>
</item>
<item>
<property name="text">
<string>1/64</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
Expand All @@ -185,7 +249,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>401</width>
<width>430</width>
<height>24</height>
</rect>
</property>
Expand All @@ -209,7 +273,14 @@
</property>
<addaction name="actionHelp"/>
</widget>
<widget class="QMenu" name="menu">
<property name="title">
<string>导入</string>
</property>
<addaction name="actionImportNote"/>
</widget>
<addaction name="exportMenu"/>
<addaction name="menu"/>
<addaction name="helpMenu"/>
<addaction name="aboutMenu"/>
</widget>
Expand Down Expand Up @@ -244,6 +315,11 @@
<string>关于本应用</string>
</property>
</action>
<action name="actionImportNote">
<property name="text">
<string>Note</string>
</property>
</action>
</widget>
<resources/>
<connections/>
Expand Down

0 comments on commit 463ada8

Please sign in to comment.