Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
Loading...
Searching...
No Matches
smf_reader.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstdint>
4#include <filesystem>
5#include <optional>
6#include <span>
7#include <string_view>
8#include <vector>
9
10namespace ts {
11
13enum class MidiEventKind {
18};
19
21struct MidiEvent {
23 std::int64_t position = 0;
27 int status = 0;
29 int data1 = 0;
31 int data2 = 0;
33 std::vector<std::uint8_t> sysex;
34
51 int port = 0;
52
54 [[nodiscard]] int channel() const noexcept { return status & 0x0F; }
55
57 [[nodiscard]] int message_type() const noexcept { return status & 0xF0; }
58};
59
69namespace smf {
70
72inline constexpr int block_grid = 32;
73
75inline constexpr int default_tempo = 500'000;
76
85struct SongLoop {
87 std::int64_t start = 0;
89 std::int64_t end = 0;
94 bool soft = false;
95};
96
98struct Song {
100 std::vector<MidiEvent> events;
102 std::optional<SongLoop> loop;
103};
104
112[[nodiscard]] Song load(const std::filesystem::path& path, int sample_rate = 32000);
113
118[[nodiscard]] Song load(std::span<const std::uint8_t> data,
119 int sample_rate = 32000,
120 std::string_view name = {});
121
123[[nodiscard]] std::vector<MidiEvent> read(const std::filesystem::path& path,
124 int sample_rate = 32000);
125
129[[nodiscard]] std::vector<MidiEvent> parse(std::span<const std::uint8_t> data,
130 int sample_rate = 32000);
131
145[[nodiscard]] std::int64_t quantise(double samples) noexcept;
146
147} // namespace smf
148} // namespace ts
A dependency-free Standard MIDI File reader.
Definition smf_reader.hpp:69
constexpr int default_tempo
Default tempo when a file sets none: 120 bpm, in microseconds per quarter note.
Definition smf_reader.hpp:75
std::vector< MidiEvent > read(const std::filesystem::path &path, int sample_rate=32000)
Reads a music file, ordered by position — load without the loop points.
std::vector< MidiEvent > parse(std::span< const std::uint8_t > data, int sample_rate=32000)
Parses a music file held in memory, ordered by position — load without the loop points.
std::int64_t quantise(double samples) noexcept
Rounds a sample position onto the render-block grid.
Song load(const std::filesystem::path &path, int sample_rate=32000)
Reads a music file, with its loop points.
constexpr int block_grid
Samples per render block — the grid events are applied on.
Definition smf_reader.hpp:72
Definition control_decode.hpp:7
MidiEventKind
What kind of message an event carries.
Definition smf_reader.hpp:13
@ sysex
A system-exclusive message, including the leading F0.
Definition smf_reader.hpp:17
@ channel
A channel voice message.
Definition smf_reader.hpp:15
One scheduled MIDI message.
Definition smf_reader.hpp:21
std::int64_t position
Position in samples, quantised to the render-block grid.
Definition smf_reader.hpp:23
int status
Status byte, for a channel message.
Definition smf_reader.hpp:27
int data2
Second data byte, or zero for two-byte messages.
Definition smf_reader.hpp:31
int channel() const noexcept
The channel a channel message addresses.
Definition smf_reader.hpp:54
int data1
First data byte.
Definition smf_reader.hpp:29
MidiEventKind kind
Which kind of message.
Definition smf_reader.hpp:25
int port
Which MIDI port the event's track was tagged for.
Definition smf_reader.hpp:51
std::vector< std::uint8_t > sysex
Raw bytes, for a system-exclusive message.
Definition smf_reader.hpp:33
int message_type() const noexcept
The message type nibble.
Definition smf_reader.hpp:57
A parsed file: the event list plus what the container knew beyond the events.
Definition smf_reader.hpp:98
std::optional< SongLoop > loop
Loop points, when the file declares any.
Definition smf_reader.hpp:102
std::vector< MidiEvent > events
Every event, ordered by position.
Definition smf_reader.hpp:100
Loop points a file declared, in samples on the render-block grid.
Definition smf_reader.hpp:85
bool soft
Whether the file marked the loop end explicitly (a soft loop).
Definition smf_reader.hpp:94
std::int64_t start
First sample of the loop body.
Definition smf_reader.hpp:87
std::int64_t end
Sample the jump back happens at.
Definition smf_reader.hpp:89