Add audio playback to gui

This commit is contained in:
illyum 2024-08-09 00:58:20 -06:00
parent e3228fa03d
commit 419ee8fd7c

View File

@ -10,7 +10,8 @@
#include <atomic>
#include <nlohmann/json.hpp>
#include <fstream>
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
#include "tinyfiledialogs.h"
@ -31,6 +32,11 @@ float bpm = 120.0f; // Default BPM
float zoom_level = 1.0f; // Zoom level
float pan_offset = 0.0f; // Pan offset
// audio stuff
ma_sound sound;
ma_engine engine;
bool audioLoaded = false;
const int num_channels = 512;
unsigned char buffer[num_channels] = { 0 };
@ -87,6 +93,11 @@ int main() {
return 1;
}
if (ma_engine_init(NULL, &engine) != MA_SUCCESS) {
std::cerr << "Failed to initialize audio engine." << std::endl;
return -1;
}
GLFWwindow* window = initOpenGL();
if (!window) {
CloseHandle(hSerial);
@ -126,6 +137,8 @@ int main() {
glfwTerminate();
CloseHandle(hSerial);
ma_engine_uninit(&engine);
return 0;
}
@ -195,6 +208,28 @@ void loadMarkersFromFile(const std::string& filename) {
}
}
void loadAndPlayAudio(const std::string& filename) {
if (audioLoaded) {
ma_sound_uninit(&sound);
}
if (ma_sound_init_from_file(&engine, filename.c_str(), MA_SOUND_FLAG_STREAM, NULL, NULL, &sound) == MA_SUCCESS) {
audioLoaded = true;
ma_sound_start(&sound);
}
else {
std::cerr << "Failed to load audio file: " << filename << std::endl;
}
}
std::string OpenAudioFileDialog() {
const char* filterPatterns[2] = { "*.mp3", "*.wav" };
const char* filename = tinyfd_openFileDialog("Select an audio file", "", 2, filterPatterns, NULL, 0);
if (filename) {
return std::string(filename);
}
return "";
}
GLFWwindow* initOpenGL() {
if (!glfwInit()) {
@ -276,6 +311,13 @@ void renderImGui() {
}
}
if (ImGui::Button("Load Audio File")) {
std::string filename = OpenAudioFileDialog();
if (!filename.empty()) {
loadAndPlayAudio(filename);
}
}
// Create sliders for the first three DMX channels
ImGui::SliderInt("Channel 1", &channel1, 0, 255);
@ -290,13 +332,45 @@ void renderImGui() {
// Allow user to set the total duration of the timeline and BPM
ImGui::SliderFloat("Timeline Duration (seconds)", &timeline_duration, 1.0f, 300.0f);
ImGui::SliderFloat("BPM", &bpm, 30.0f, 240.0f);
ImGui::SameLine();
ImGui::SetNextItemWidth(50);
if (ImGui::InputFloat("##BPMInput", &bpm, 0.0f, 0.0f, "%.1f")) {
if (bpm < 30.0f) bpm = 30.0f;
if (bpm > 240.0f) bpm = 240.0f;
}
// Play/Pause button
if (ImGui::Button(is_playing ? "Pause" : "Play")) {
is_playing = !is_playing;
if (is_playing) {
playback_start_time = static_cast<float>(glfwGetTime()) - timeline_position;
if (audioLoaded) {
ma_uint64 frameCount;
ma_sound_get_length_in_pcm_frames(&sound, &frameCount);
// Calculate the frame to seek to based on the timeline position
ma_uint64 targetFrame = static_cast<ma_uint64>((timeline_position / timeline_duration) * frameCount);
ma_sound_seek_to_pcm_frame(&sound, targetFrame);
ma_sound_start(&sound);
}
}
else {
if (audioLoaded) {
ma_sound_stop(&sound);
}
}
}
// Stop Music button
ImGui::SameLine();
if (ImGui::Button("Stop Music")) {
if (audioLoaded) {
ma_sound_stop(&sound);
}
is_playing = false;
timeline_position = 0.0f;
}
// Time Slider (Timeline Position)
@ -356,23 +430,25 @@ void renderImGui() {
current_time = static_cast<float>(glfwGetTime()) - playback_start_time;
timeline_position = current_time;
// Trigger markers during playback
for (const auto& marker : markers) {
float marker_time = std::get<0>(marker) * timeline_duration;
if (current_time >= marker_time && current_time < marker_time + 0.025f) { // Slight tolerance for timing precision
if (current_time >= marker_time && current_time < marker_time + 0.025f) {
buffer[0] = std::get<1>(marker);
buffer[1] = std::get<2>(marker);
buffer[2] = std::get<3>(marker);
}
}
// Stop playback when the timeline reaches the end
if (timeline_position >= timeline_duration) {
is_playing = false;
timeline_position = timeline_duration;
if (audioLoaded) {
ma_sound_stop(&sound);
}
}
}
// Display added markers with their RGB values and time
for (const auto& marker : markers) {
float marker_time = std::get<0>(marker) * timeline_duration;