Add audio playback to gui
This commit is contained in:
parent
e3228fa03d
commit
419ee8fd7c
84
main.cpp
84
main.cpp
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user