Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactors note value to use pitch with tuning #138

Merged
merged 5 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ instrument.SetControl(barely::SynthInstrument::Control::kGain, /*value=*/0.5);

// Set an instrument note on.
//
// Note values for pitched instruments typically represent the frequencies of the corresponding
// notes. However, this is not a strict rule, as the `note` and `intensity` values can be
// interpreted in any desired way by a custom instrument.
instrument.SetNoteOn(/*note=*/220.0, /*intensity=*/0.25);
// Note values typically follow the MIDI Standard Tuning for convenience, where `pitch` represents
// the MIDI note number, and `intensity` represents the normalized MIDI note velocity. However, this
// is not a strict rule, as the `pitch` and `intensity` values can be interpreted in any desired way
// by a custom instrument with a custom tuning.
instrument.SetNoteOn(/*pitch=*/60, /*intensity=*/0.25);

// Check if the instrument note is on.
const bool is_note_on = instrument.IsNoteOn(/*note=*/220.0); // will return true.
const bool is_note_on = instrument.IsNoteOn(/*note=*/60); // will return true.

// Create a low-pass effect.
barely::Effect effect(musician, barely::LowPassEffect::GetDefinition());
Expand All @@ -71,9 +72,9 @@ Task task(
performer,
[&]() {
// Set an instrument note on.
instrument.SetNoteOn(/*note=*/440.0);
instrument.SetNoteOn(/*pitch=*/62);
// Schedule a one-off task to set the instrument note off after half a beat.
performer.ScheduleOneOffTask([&]() { instrument.SetNoteOff(/*note=*/440.0); },
performer.ScheduleOneOffTask([&]() { instrument.SetNoteOff(/*pitch=*/62); },
performer.GetPosition() + 0.5);
});

Expand Down
55 changes: 41 additions & 14 deletions barelymusician/barelymusician.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "barelymusician/barelymusician.h"

#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdint>

Expand Down Expand Up @@ -253,24 +254,24 @@ bool BarelyInstrument_GetControl(const BarelyInstrument* instrument, int32_t id,
return false;
}

bool BarelyInstrument_GetNoteControl(const BarelyInstrument* instrument, double note, int32_t id,
bool BarelyInstrument_GetNoteControl(const BarelyInstrument* instrument, int32_t pitch, int32_t id,
double* out_value) {
if (!instrument) return false;
if (!out_value) return false;

if (const auto* note_control = instrument->GetNoteControl(note, id); note_control != nullptr) {
if (const auto* note_control = instrument->GetNoteControl(pitch, id); note_control != nullptr) {
*out_value = note_control->GetValue();
return true;
}
return false;
}

bool BarelyInstrument_IsNoteOn(const BarelyInstrument* instrument, double note,
bool BarelyInstrument_IsNoteOn(const BarelyInstrument* instrument, int32_t pitch,
bool* out_is_note_on) {
if (!instrument) return false;
if (!out_is_note_on) return false;

*out_is_note_on = instrument->IsNoteOn(note);
*out_is_note_on = instrument->IsNoteOn(pitch);
return true;
}

Expand All @@ -290,10 +291,10 @@ bool BarelyInstrument_ResetAllControls(BarelyInstrument* instrument) {
return true;
}

bool BarelyInstrument_ResetAllNoteControls(BarelyInstrument* instrument, double note) {
bool BarelyInstrument_ResetAllNoteControls(BarelyInstrument* instrument, int32_t pitch) {
if (!instrument) return false;

return instrument->ResetAllNoteControls(note);
return instrument->ResetAllNoteControls(pitch);
}

bool BarelyInstrument_ResetControl(BarelyInstrument* instrument, int32_t id) {
Expand All @@ -306,10 +307,10 @@ bool BarelyInstrument_ResetControl(BarelyInstrument* instrument, int32_t id) {
return false;
}

bool BarelyInstrument_ResetNoteControl(BarelyInstrument* instrument, double note, int32_t id) {
bool BarelyInstrument_ResetNoteControl(BarelyInstrument* instrument, int32_t pitch, int32_t id) {
if (!instrument) return false;

if (auto* note_control = instrument->GetNoteControl(note, id); note_control != nullptr) {
if (auto* note_control = instrument->GetNoteControl(pitch, id); note_control != nullptr) {
note_control->ResetValue();
return true;
}
Expand Down Expand Up @@ -350,11 +351,11 @@ bool BarelyInstrument_SetData(BarelyInstrument* instrument, const void* data, in
return true;
}

bool BarelyInstrument_SetNoteControl(BarelyInstrument* instrument, double note, int32_t id,
bool BarelyInstrument_SetNoteControl(BarelyInstrument* instrument, int32_t pitch, int32_t id,
double value) {
if (!instrument) return false;

if (auto* note_control = instrument->GetNoteControl(note, id); note_control != nullptr) {
if (auto* note_control = instrument->GetNoteControl(pitch, id); note_control != nullptr) {
note_control->SetValue(value);
return true;
}
Expand All @@ -370,10 +371,10 @@ bool BarelyInstrument_SetNoteControlEvent(BarelyInstrument* instrument,
return true;
}

bool BarelyInstrument_SetNoteOff(BarelyInstrument* instrument, double note) {
bool BarelyInstrument_SetNoteOff(BarelyInstrument* instrument, int32_t pitch) {
if (!instrument) return false;

instrument->SetNoteOff(note);
instrument->SetNoteOff(pitch);
return true;
}

Expand All @@ -385,10 +386,10 @@ bool BarelyInstrument_SetNoteOffEvent(BarelyInstrument* instrument,
return true;
}

bool BarelyInstrument_SetNoteOn(BarelyInstrument* instrument, double note, double intensity) {
bool BarelyInstrument_SetNoteOn(BarelyInstrument* instrument, int32_t pitch, double intensity) {
if (!instrument) return false;

instrument->SetNoteOn(note, intensity);
instrument->SetNoteOn(pitch, intensity);
return true;
}

Expand All @@ -400,6 +401,14 @@ bool BarelyInstrument_SetNoteOnEvent(BarelyInstrument* instrument,
return true;
}

bool BarelyInstrument_SetTuning(BarelyInstrument* instrument,
const BarelyTuningDefinition* definition) {
if (!instrument) return false;

instrument->SetTuning(reinterpret_cast<const barely::TuningDefinition*>(definition));
return true;
}

bool BarelyMusician_Create(int32_t frame_rate, BarelyMusician** out_musician) {
if (frame_rate <= 0) return false;
if (!out_musician) return false;
Expand Down Expand Up @@ -607,3 +616,21 @@ bool BarelyTask_SetPosition(BarelyTask* task, double position) {
task->SetPosition(position);
return true;
}

bool BarelyTuningDefinition_GetFrequency(const BarelyTuningDefinition* definition, int32_t pitch,
double* out_frequency) {
if (!definition) return false;
if (definition->pitch_ratios == nullptr || definition->pitch_ratio_count == 0) return false;
if (out_frequency == nullptr) return false;

const int pitch_count = static_cast<int>(definition->pitch_ratio_count);
const int relative_pitch = pitch - definition->root_pitch;
const int octave = static_cast<int>(
std::floor(static_cast<double>(relative_pitch) / static_cast<double>(pitch_count)));
const int index = relative_pitch - octave * pitch_count;
assert(index >= 0 && index < pitch_count);
*out_frequency = definition->root_frequency *
std::pow(definition->pitch_ratios[pitch_count - 1], octave) *
(index > 0 ? definition->pitch_ratios[index - 1] : 1.0);
return true;
}
Loading