Skip to content

Commit

Permalink
Draw bar and note text
Browse files Browse the repository at this point in the history
  • Loading branch information
twollgam committed Mar 23, 2024
1 parent b22122f commit 59ed6ec
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 31 deletions.
26 changes: 26 additions & 0 deletions game/guitar/guitar_strings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@

#include <cmath>
#include <stdexcept>
#include <vector>

namespace {
const std::vector<Frequency> standardTuningFreqs = { 82.41f, 110.00f, 146.83f, 196.00f, 246.94f, 329.63f };

StringName findClosestString(Frequency frequency) {
auto closestStringIndex = size_t(0);
auto minDifference = std::numeric_limits<Frequency>::max();

// Iterate through standard tuning frequencies and find the closest one
for (size_t i = 0; i < standardTuningFreqs.size(); ++i) {
auto difference = std::abs(frequency - standardTuningFreqs[i]);

if (difference < minDifference) {
minDifference = difference;
closestStringIndex = i;
}
}

return static_cast<StringName>(closestStringIndex);
}
}

StringName GuitarStrings::getString(Frequency frequency) const {
return findClosestString(frequency);
}

Frequency GuitarStrings::getFrequency(StringName string, int fret) const {
auto const base = getBaseFrequency(string);
Expand Down
1 change: 1 addition & 0 deletions game/guitar/guitar_strings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ enum class StringName {

class GuitarStrings {
public:
StringName getString(Frequency frequency) const;
Frequency getFrequency(StringName string, int fret = 0) const;
Frequency getBaseFrequency(StringName string) const;
};
74 changes: 44 additions & 30 deletions game/screen_guitar_tuner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "progressbar.hh"
#include "game.hh"
#include "analyzer.hh"
#include <guitar/guitar_strings.hh>



Expand All @@ -16,8 +17,12 @@ ScreenGuitarTuner::ScreenGuitarTuner(Game& game, std::string const& name, Audio&
}

void ScreenGuitarTuner::enter() {
m_audio.fadeout(getGame());

for (size_t i = 0, mics = m_audio.analyzers().size(); i < mics; ++i) {
m_vumeters.emplace_back(std::make_unique<ProgressBar>(findFile("vumeter_bg.svg"), findFile("vumeter_fg.svg"), ProgressBar::Mode::VERTICAL, 0.136, 0.023));
m_bars.emplace_back();
for(auto n = 0; n < 7; ++n)
m_bars[i].emplace_back(std::make_unique<Texture>(findFile("bar.svg")));
}

reloadGL();
Expand All @@ -30,7 +35,7 @@ void ScreenGuitarTuner::reloadGL() {

void ScreenGuitarTuner::exit() {
getGame().controllers.enableEvents(false);
m_vumeters.clear();
m_bars.clear();
m_theme.reset();
}

Expand All @@ -51,27 +56,32 @@ void ScreenGuitarTuner::manageEvent(input::NavEvent const& event) {
void ScreenGuitarTuner::draw() {
auto& window = getGame().getWindow();

auto const width = m_theme->fretWidth;
auto const height = m_theme->fretHeight;
auto const left = width * -0.5f;
auto const top = height * -0.5f;

m_theme->bg.draw(window);
m_theme->fret.dimensions.left(-0.25f).top(-0.15f).stretch(0.5f, 0.3f);
m_theme->fret.dimensions.left(left).top(top).stretch(width, height);
m_theme->fret.draw(window);

draw_analyzers();
}

void ScreenGuitarTuner::draw_analyzers() {
auto& window = getGame().getWindow();

//m_theme->note.dimensions.fixedHeight(0.03f);
//m_theme->sharp.dimensions.fixedHeight(0.09f);

auto& analyzers = m_audio.analyzers();

if (analyzers.empty())
return;

auto const paddingTop = m_theme->paddingTop;
auto const paddingBottom = m_theme->paddingBottom;
auto const height = m_theme->fretHeight - m_theme->fretHeight * (paddingTop + paddingBottom);

MusicalScale scale;
double textPower = -getInf();
double textFreq = 0.0;
auto textPower = -getInf();
auto textFreq = 0.0;

for (unsigned int i = 0; i < analyzers.size(); ++i) {
auto& analyzer = analyzers[i];
Expand All @@ -84,35 +94,39 @@ void ScreenGuitarTuner::draw_analyzers() {
textPower = tone->db;
textFreq = freq;
}
// getPeak returns 0.0 when clipping, negative values when not that loud.
// Normalizing to [0,1], where 0 is -43 dB or less (to match the vumeter graphic)
m_vumeters[i]->dimensions.screenBottom().left(-0.4f + static_cast<float>(i) * 0.08f).fixedWidth(0.04f); //0.08 was originally 0.2. Now 11 in a row fits
m_vumeters[i]->draw(window, static_cast<float>(analyzer.getPeak() / 43.0 + 1.0));

if (freq != 0.0) {
auto tones = analyzer.getTones();
auto const tones = analyzer.getTones();
auto n = 0U;

for (auto t = tones.begin(); t != tones.end(); ++t) {
if (t->age < Tone::MINAGE)
continue;
if (!scale.setFreq(t->freq).isValid())
for (auto& tone : tones) {
if (tone.age < Tone::MINAGE)
continue;
//if (!scale.setFreq(tone.freq).isValid())
// continue;

auto const string = GuitarStrings().getString(static_cast<Frequency>(tone.freq));
auto const base = GuitarStrings().getBaseFrequency(string);
auto const difference = base - static_cast<Frequency>(tone.freq);
auto const x = difference / base;
auto const line = static_cast<float>(static_cast<int>(string)) / 5.f;
auto const y = height * (-0.5f + line);

m_bars[i][n]->dimensions.middle(x).center(y).stretch(0.04f, 0.04f /* * static_cast<float>(tone.db) / 40.f*/);
m_bars[i][n]->draw(window);

double line = scale.getNoteLine() + 0.4 * scale.getNoteOffset();
float posXnote = static_cast<float>(-0.25 + 0.2 * i + 0.002 * t->stabledb); // Wiggle horizontally based on volume
float posYnote = static_cast<float>(-0.03 - line * 0.015); // On treble key (C4), plus offset (lines)

//m_theme->note.dimensions.left(posXnote).center(posYnote);
//m_theme->note.draw(window);
// Draw # for sharp notes
if (scale.isSharp()) {
//m_theme->sharp.dimensions.right(posXnote).center(posYnote);
//m_theme->sharp.draw(window);
}
if (++n == m_bars[i].size())
break;
}
}
}

if (textFreq > 0.0)
if (textFreq > 0.0) {
auto const string = GuitarStrings().getString(static_cast<Frequency>(textFreq));
auto const line = static_cast<float>(static_cast<int>(string)) / 5.f;
auto const y = height * (-0.5f + line);

m_theme->note_txt.dimensions.center(y).right(m_theme->fretWidth * -0.5f - 0.2f);
m_theme->note_txt.draw(window, scale.setFreq(textFreq).getStr());
}
}
2 changes: 1 addition & 1 deletion game/screen_guitar_tuner.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ public:
private:
Audio& m_audio;
std::vector<std::string> m_samples;
std::vector<std::unique_ptr<ProgressBar>> m_vumeters;
std::vector<std::vector<std::unique_ptr<Texture>>> m_bars;
std::unique_ptr<ThemeGuitarTuner> m_theme;
};
1 change: 1 addition & 0 deletions game/theme.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ThemePractice::ThemePractice():
ThemeGuitarTuner::ThemeGuitarTuner()
: Theme(findFile("bg_guitar_tuner.svg")),
fret(findFile("Guitar6Strings.png")),
bar(findFile("bar.svg")),
note_txt(findFile("practice_txt.svg"), config["graphic/text_lod"].f()) {
}

Expand Down
7 changes: 7 additions & 0 deletions game/theme.hh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ public:
ThemeGuitarTuner();

Texture fret;
Texture bar;
SvgTxtTheme note_txt;
float fretWidth = 0.5f;
float fretHeight = 0.3f;
float paddingLeft = 0.f;
float paddingRight = 0.f;
float paddingTop = 31.f / 278.f;
float paddingBottom = 21.f / 278.f;
};

/// theme for singing screen
Expand Down
31 changes: 31 additions & 0 deletions testing/guitar_strings_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,34 @@ TEST(UnitTest_GuitarStrings, getFrequency_fret_12) {
EXPECT_NEAR(493.88f, GuitarStrings().getFrequency(StringName::B, 12), 0.1f);
EXPECT_NEAR(659.26f, GuitarStrings().getFrequency(StringName::E_High, 12), 0.1f);
}

TEST(UnitTest_GuitarStrings, getString_E_LOW) {
EXPECT_EQ(GuitarStrings().getString(82.0f), StringName::E_Low);
EXPECT_EQ(GuitarStrings().getString(83.0f), StringName::E_Low);
}

TEST(UnitTest_GuitarStrings, getString_A) {
EXPECT_EQ(GuitarStrings().getString(108.0f), StringName::A);
EXPECT_EQ(GuitarStrings().getString(112.0f), StringName::A);
}

TEST(UnitTest_GuitarStrings, getString_D) {
EXPECT_EQ(GuitarStrings().getString(145.0f), StringName::D);
EXPECT_EQ(GuitarStrings().getString(147.0f), StringName::D);
}

TEST(UnitTest_GuitarStrings, getString_G) {
EXPECT_EQ(GuitarStrings().getString(194.0f), StringName::G);
EXPECT_EQ(GuitarStrings().getString(198.0f), StringName::G);
}

TEST(UnitTest_GuitarStrings, getString_B) {
EXPECT_EQ(GuitarStrings().getString(240.0f), StringName::B);
EXPECT_EQ(GuitarStrings().getString(248.0f), StringName::B);
}

TEST(UnitTest_GuitarStrings, getString_E_HIGH) {
EXPECT_EQ(GuitarStrings().getString(325.0f), StringName::E_High);
EXPECT_EQ(GuitarStrings().getString(330.0f), StringName::E_High);
}

0 comments on commit 59ed6ec

Please sign in to comment.