diff options
| -rw-r--r-- | src/test_demo.cc | 33 | ||||
| -rw-r--r-- | test_demo_README.md | 62 |
2 files changed, 80 insertions, 15 deletions
diff --git a/src/test_demo.cc b/src/test_demo.cc index 1664f7c..5f36e30 100644 --- a/src/test_demo.cc +++ b/src/test_demo.cc @@ -28,11 +28,14 @@ static void print_usage(const char* prog_name) { printf(" --resolution WxH Set window resolution (e.g., 1024x768)\n"); printf(" --tempo Enable tempo variation test mode\n"); printf(" (alternates between acceleration and deceleration)\n"); - printf(" --log-peaks FILE Log audio peaks to FILE for gnuplot visualization\n"); + printf(" --log-peaks FILE Log audio peaks at each beat (32 samples for 16s)\n"); + printf(" --log-peaks-fine Log at each frame for fine analysis (~960 samples)\n"); + printf(" (use with --log-peaks for millisecond resolution)\n"); printf("\nExamples:\n"); printf(" %s --fullscreen\n", prog_name); printf(" %s --resolution 1024x768 --tempo\n", prog_name); printf(" %s --log-peaks peaks.txt\n", prog_name); + printf(" %s --log-peaks peaks.txt --log-peaks-fine\n", prog_name); printf("\nControls:\n"); printf(" ESC Exit the demo\n"); printf(" F Toggle fullscreen\n"); @@ -47,6 +50,7 @@ int main(int argc, char** argv) { int width = 1280; int height = 720; const char* log_peaks_file = nullptr; + bool log_peaks_fine = false; #if !defined(STRIP_ALL) for (int i = 1; i < argc; ++i) { @@ -66,6 +70,8 @@ int main(int argc, char** argv) { } } else if (strcmp(argv[i], "--log-peaks") == 0 && i + 1 < argc) { log_peaks_file = argv[++i]; + } else if (strcmp(argv[i], "--log-peaks-fine") == 0) { + log_peaks_fine = true; } } #else @@ -131,15 +137,21 @@ int main(int argc, char** argv) { peak_log = fopen(log_peaks_file, "w"); if (peak_log) { fprintf(peak_log, "# Audio peak log from test_demo\n"); + fprintf(peak_log, "# Mode: %s\n", log_peaks_fine ? "fine (per-frame)" : "beat-aligned"); fprintf(peak_log, "# To plot with gnuplot:\n"); - fprintf(peak_log, "# gnuplot -p -e \"set xlabel 'Time (s)'; set ylabel 'Peak'; plot '%s' using 1:3 with lines title 'Raw Peak'\"\n", log_peaks_file); - fprintf(peak_log, "# Columns: beat_number clock_time raw_peak\n"); + fprintf(peak_log, "# gnuplot -p -e \"set xlabel 'Time (s)'; set ylabel 'Peak'; plot '%s' using 2:3 with lines title 'Raw Peak'\"\n", log_peaks_file); + if (log_peaks_fine) { + fprintf(peak_log, "# Columns: frame_number clock_time raw_peak\n"); + } else { + fprintf(peak_log, "# Columns: beat_number clock_time raw_peak\n"); + } fprintf(peak_log, "#\n"); } else { fprintf(stderr, "Warning: Could not open log file '%s'\n", log_peaks_file); } } int last_beat_logged = -1; + int frame_number = 0; #endif // Main loop @@ -177,11 +189,18 @@ int main(int argc, char** argv) { const float beat = fmodf(beat_time, 1.0f); #if !defined(STRIP_ALL) - // Log peak at each beat boundary - if (peak_log && beat_number != last_beat_logged) { - fprintf(peak_log, "%d %.6f %.6f\n", beat_number, current_time, raw_peak); - last_beat_logged = beat_number; + // Log peak (either per-frame or per-beat) + if (peak_log) { + if (log_peaks_fine) { + // Log every frame for fine-grained analysis + fprintf(peak_log, "%d %.6f %.6f\n", frame_number, current_time, raw_peak); + } else if (beat_number != last_beat_logged) { + // Log only at beat boundaries + fprintf(peak_log, "%d %.6f %.6f\n", beat_number, current_time, raw_peak); + last_beat_logged = beat_number; + } } + frame_number++; // Debug output every 0.5 seconds static float last_print_time = -1.0f; diff --git a/test_demo_README.md b/test_demo_README.md index f84f972..b8abfc2 100644 --- a/test_demo_README.md +++ b/test_demo_README.md @@ -34,7 +34,9 @@ build/test_demo --fullscreen Run in fullscreen mode --resolution WxH Set window resolution (e.g., 1024x768) --tempo Enable tempo variation test mode - --log-peaks FILE Log audio peaks to FILE for gnuplot visualization + --log-peaks FILE Log audio peaks at each beat (32 samples for 16s) + --log-peaks-fine Log at each frame for fine analysis (~960 samples) + (use with --log-peaks for millisecond resolution) ``` ### Examples @@ -49,16 +51,23 @@ build/test_demo --fullscreen build/test_demo --resolution 1024x768 --tempo ``` -#### Log audio peaks for analysis +#### Log audio peaks for analysis (beat-aligned) ```bash build/test_demo --log-peaks peaks.txt ``` After running, visualize with gnuplot: ```bash -gnuplot -p -e "set xlabel 'Time (s)'; set ylabel 'Peak'; plot 'peaks.txt' using 1:3 with lines title 'Raw Peak'" +gnuplot -p -e "set xlabel 'Time (s)'; set ylabel 'Peak'; plot 'peaks.txt' using 2:3 with lines title 'Raw Peak'" ``` +#### Log audio peaks with fine resolution (every frame) +```bash +build/test_demo --log-peaks peaks_fine.txt --log-peaks-fine +``` + +This logs at ~60 Hz (every frame) instead of every beat, providing millisecond-resolution data for detailed synchronization analysis. Produces ~960 samples for the 16-second demo. + ## Keyboard Controls - **ESC**: Exit the demo @@ -109,12 +118,17 @@ This tests the variable tempo system where music time advances independently of ## Peak Logging Format -The `--log-peaks` option writes a text file with three columns: +The `--log-peaks` option writes a text file with three columns. + +### Beat-Aligned Mode (default) + +Logs once per beat (32 samples for 16 seconds): ``` # Audio peak log from test_demo +# Mode: beat-aligned # To plot with gnuplot: -# gnuplot -p -e "set xlabel 'Time (s)'; set ylabel 'Peak'; plot 'peaks.txt' using 1:3 with lines title 'Raw Peak'" +# gnuplot -p -e "set xlabel 'Time (s)'; set ylabel 'Peak'; plot 'peaks.txt' using 2:3 with lines title 'Raw Peak'" # Columns: beat_number clock_time raw_peak # 0 0.000000 0.850000 @@ -128,12 +142,44 @@ The `--log-peaks` option writes a text file with three columns: 2. **clock_time**: Physical time in seconds 3. **raw_peak**: Audio peak value (0.0-1.0+) +### Fine-Grained Mode (`--log-peaks-fine`) + +Logs at every frame (approximately 960 samples for 16 seconds at 60 Hz): + +``` +# Audio peak log from test_demo +# Mode: fine (per-frame) +# To plot with gnuplot: +# gnuplot -p -e "set xlabel 'Time (s)'; set ylabel 'Peak'; plot 'peaks_fine.txt' using 2:3 with lines title 'Raw Peak'" +# Columns: frame_number clock_time raw_peak +# +0 0.000000 0.850000 +1 0.016667 0.845231 +2 0.033333 0.823445 +3 0.050000 0.802891 +... +``` + +**Columns:** +1. **frame_number**: Frame index (0, 1, 2, ...) +2. **clock_time**: Physical time in seconds (millisecond precision) +3. **raw_peak**: Audio peak value (0.0-1.0+) + **Use Cases:** -- Verify audio/visual synchronization timing -- Detect clipping (peak > 1.0) -- Analyze tempo scaling effects + +*Beat-Aligned Mode:* +- Verify audio/visual synchronization at beat boundaries +- Detect clipping at specific beats (peak > 1.0) +- Analyze tempo scaling effects on pattern triggering - Compare expected vs actual beat times +*Fine-Grained Mode:* +- Millisecond-resolution synchronization analysis +- Detect frame-level timing jitter or drift +- Analyze audio envelope shape and attack/decay characteristics +- Debug precise flash-to-audio alignment issues +- Identify sub-beat audio artifacts or glitches + ## Files - **`src/test_demo.cc`**: Main executable (~220 lines) |
