-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsstvprocessor.cpp
More file actions
80 lines (68 loc) · 2.36 KB
/
Copy pathsstvprocessor.cpp
File metadata and controls
80 lines (68 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include "sstvprocessor.hpp"
#include "langs.hpp"
MidiNoteToImage::MidiNoteToImage(const std::string& midi_file_path, unsigned char track_number, sstvformats_ sstvformat_)
{
smf::MidiFile midifile;
if (!midifile.read(midi_file_path)) {
throw std::runtime_error(midifilecannotberead_bmj + midi_file_path);
}
midifile.linkNotePairs();
midifile.doTimeAnalysis();
for (int event = 0; event < midifile[track_number].size(); event++) {
smf::MidiEvent& mev = midifile[track_number][event];
if (mev.isNoteOn()) {
if (midiPitchToFrequency(mev[1]) <= BLACK_AUDIO_FREQ || midiPitchToFrequency(mev[1]) >= WHITE_AUDIO_FREQ) continue;
double start_time = mev.seconds;
smf::MidiEvent* note_off = mev.getLinkedEvent();
if (note_off) {
double end_time = mev.seconds;
notes.push_back({ midiPitchToFrequency(mev[1]), start_time, end_time });
}
}
}
notes.sort([](const Note& a, const Note& b) {
return a.start_time < b.start_time;
});
auto it = notes.begin();
while (it != notes.end()) {
auto next = std::next(it);
while (next != notes.end() && std::abs(next->start_time - it->start_time) < 0.001) {
it->pitch = std::max(it->pitch, next->pitch);
it->end_time = std::max(it->end_time, next->end_time);
next = notes.erase(next);
}
++it;
}
}
const MidiNoteToImage::sstvformats_& MidiNoteToImage::getSSTVformat() const
{
return sstvformat;
}
inline double MidiNoteToImage::midiPitchToFrequency(int pitch, double a4_freq)
{
return a4_freq * pow(2.0, (pitch - 69) / 12.0);
}
void MidiNoteToImage::generateBitImage()
{
double color_time;
switch (sstvformat)
{
case martin1: color_time = MARTIN1_SINGLEPIXEL_TIME; break;
case martin2: color_time = MARTIN2_SINGLEPIXEL_TIME; break;
case scottie1: color_time = SCOTTIE1_SINGLEPIXEL_TIME; break;
case scottie2: color_time = SCOTTIE2_SINGLEPIXEL_TIME; break;
case scottiedx: color_time = SCOTTIEDX_SINGLEPIXEL_TIME; break;
}
for (auto i = notes.begin(); i != notes.end(); ++i)
{
if ((unsigned int)((i->start_time) / color_time) >= SSTV_WIDTH * SSTV_HEIGHT * 3) break;
for (unsigned int j = (unsigned int)((i->start_time) / color_time);
(j < SSTV_WIDTH * SSTV_HEIGHT * 3) && (j < (unsigned int)((i->end_time) / color_time));
++j)
{
sstvbitimage[j] = (unsigned char)(((i->pitch - 1500.0) / (2300.0 - 1500.0)) * 255.0);
}
}
}