Last active
April 27, 2024 17:33
-
-
Save eXpl0it3r/8907ff523a2de985d41fcd76665714d8 to your computer and use it in GitHub Desktop.
VisualSound with SFML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <deque> | |
#include <mutex> | |
#include <SFML/Audio.hpp> | |
#include <SFML/Graphics.hpp> | |
class MusicVisualizer : public sf::Music, public sf::Drawable | |
{ | |
public: | |
void update(const sf::Time& deltaTime); | |
protected: | |
[[nodiscard]] bool onGetData(Chunk& data) override; | |
void draw(sf::RenderTarget& target, sf::RenderStates states) const override; | |
private: | |
std::recursive_mutex m_mutex; | |
std::deque<std::uint16_t> m_queue; | |
std::vector<sf::Vertex> m_vertices; | |
}; | |
bool MusicVisualizer::onGetData(Chunk& data) | |
{ | |
auto result = Music::onGetData(data); | |
{ | |
std::lock_guard lock(m_mutex); | |
for (auto i = 0u; i < data.sampleCount; ++i) | |
{ | |
m_queue.emplace_back(data.samples[i]); | |
} | |
} | |
return result; | |
} | |
void MusicVisualizer::draw(sf::RenderTarget& target, sf::RenderStates states) const | |
{ | |
target.draw(m_vertices.data(), m_vertices.size(), sf::PrimitiveType::Points, states); | |
} | |
void MusicVisualizer::update(const sf::Time& deltaTime) | |
{ | |
m_vertices.clear(); | |
{ | |
std::lock_guard lock(m_mutex); | |
auto size = std::min(static_cast<unsigned int>(m_queue.size()), 1920u); | |
m_vertices.reserve(size); | |
for (auto i = 0u; i < size; ++i) | |
{ | |
auto vertex = sf::Vertex{ {static_cast<float>(i), 0.01f * static_cast<float>(m_queue[i]) + 200.f}, sf::Color::Green}; | |
m_vertices.emplace_back(vertex); | |
} | |
} | |
for (auto i = 0u; !m_queue.empty() && i < static_cast<unsigned int>(deltaTime.asSeconds() * getSampleRate() * getChannelCount()); ++i) | |
{ | |
m_queue.pop_front(); | |
} | |
} | |
int main() | |
{ | |
auto window = sf::RenderWindow{ sf::VideoMode{ { 1920u, 1080u } }, "CMake SFML Project" }; | |
window.setFramerateLimit(144); | |
auto visualizer = MusicVisualizer(); | |
if (!visualizer.openFromFile("epic-hollywood-trailer-9489.mp3")) | |
{ | |
return -1; | |
} | |
visualizer.setLoop(true); | |
visualizer.play(); | |
auto clock = sf::Clock{}; | |
while (window.isOpen()) | |
{ | |
for (auto event = sf::Event{}; window.pollEvent(event);) | |
{ | |
if (event.type == sf::Event::Closed) | |
{ | |
window.close(); | |
} | |
} | |
auto deltaTime = clock.restart(); | |
visualizer.update(deltaTime); | |
window.clear(); | |
window.draw(visualizer); | |
window.display(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment