summaryrefslogtreecommitdiff
path: root/tools/spectool.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/spectool.cc')
-rw-r--r--tools/spectool.cc80
1 files changed, 75 insertions, 5 deletions
diff --git a/tools/spectool.cc b/tools/spectool.cc
index 29a2952..7733b98 100644
--- a/tools/spectool.cc
+++ b/tools/spectool.cc
@@ -4,6 +4,7 @@
#include "audio/audio.h"
#include "audio/dct.h"
+#include "audio/gen.h"
#include "audio/synth.h"
#include "audio/window.h"
#include "platform.h"
@@ -12,6 +13,9 @@
#include "miniaudio.h"
+#include <math.h>
+#include <stdlib.h>
+#include <time.h>
#include <vector>
// Simple .spec file format:
@@ -149,6 +153,60 @@ int play_spec(const char *in_path) {
return 0;
}
+int test_gen(const char *out_path) {
+ printf("Generating test spectrogram -> %s\n", out_path);
+
+ std::vector<float> track_data;
+ int track_frames = 0;
+
+ // Generate a simple C Major scale
+ float freqs[] = {261.63f, 293.66f, 329.63f, 349.23f, 392.00f, 440.00f, 493.88f, 523.25f};
+
+ srand(time(NULL));
+
+ for (int i = 0; i < 8; ++i) {
+ NoteParams params;
+ params.base_freq = freqs[i];
+ params.duration_sec = 0.5f;
+ params.amplitude = 0.5f;
+ params.attack_sec = 0.05f;
+ params.decay_sec = 0.1f;
+ params.vibrato_rate = 5.0f;
+ params.vibrato_depth = 2.0f;
+ params.num_harmonics = 5;
+ params.harmonic_decay = 0.5f;
+ params.pitch_randomness = 1.0f;
+ params.amp_randomness = 0.05f;
+
+ int note_frames = 0;
+ std::vector<float> note_data = generate_note_spectrogram(params, &note_frames);
+
+ // Paste at 0.4s intervals (overlap)
+ int offset = (int)(i * 0.4f * 32000.0f / DCT_SIZE);
+ paste_spectrogram(track_data, &track_frames, note_data, note_frames, offset);
+ }
+
+ // Write to file (Duplicate logic, but fine for now)
+ FILE *f_out = fopen(out_path, "wb");
+ if (!f_out) {
+ printf("Error: Failed to open output file: %s\n", out_path);
+ return 1;
+ }
+
+ SpecHeader header;
+ memcpy(header.magic, "SPEC", 4);
+ header.version = 1;
+ header.dct_size = DCT_SIZE;
+ header.num_frames = track_frames;
+
+ fwrite(&header, sizeof(SpecHeader), 1, f_out);
+ fwrite(track_data.data(), sizeof(float), track_data.size(), f_out);
+ fclose(f_out);
+
+ printf("Generated %d frames.\n", track_frames);
+ return 0;
+}
+
void print_usage() {
printf("Usage: spectool <command> <input> [output]\n");
printf("Commands:\n");
@@ -156,26 +214,38 @@ void print_usage() {
"save as a spectrogram.\n");
printf(
" play <input.spec> Play a spectrogram file.\n");
+ printf(" test_gen <output.spec> Generate a test spectrogram.\n");
}
int main(int argc, char **argv) {
- if (argc < 3) {
+ if (argc < 2) {
print_usage();
return 1;
}
const char *command = argv[1];
- const char *input_path = argv[2];
if (strcmp(command, "analyze") == 0) {
if (argc < 4) {
- printf("Error: 'analyze' command requires an output file.\n");
+ printf("Error: 'analyze' command requires input and output files.\n");
print_usage();
return 1;
}
- return analyze_audio(input_path, argv[3]);
+ return analyze_audio(argv[2], argv[3]);
} else if (strcmp(command, "play") == 0) {
- return play_spec(input_path);
+ if (argc < 3) {
+ printf("Error: 'play' command requires an input file.\n");
+ print_usage();
+ return 1;
+ }
+ return play_spec(argv[2]);
+ } else if (strcmp(command, "test_gen") == 0) {
+ if (argc < 3) {
+ printf("Error: 'test_gen' command requires an output file.\n");
+ print_usage();
+ return 1;
+ }
+ return test_gen(argv[2]);
} else {
printf("Error: Unknown command '%s'\n", command);
print_usage();