summaryrefslogtreecommitdiff
path: root/src/audio/tracker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio/tracker.cc')
-rw-r--r--src/audio/tracker.cc75
1 files changed, 42 insertions, 33 deletions
diff --git a/src/audio/tracker.cc b/src/audio/tracker.cc
index 9f9263d..5d99a45 100644
--- a/src/audio/tracker.cc
+++ b/src/audio/tracker.cc
@@ -1,8 +1,7 @@
-// This file is part of the 64k demo project.
-// It implements the tracker runtime logic.
-
#include "tracker.h"
+#include "audio.h"
#include "audio/synth.h"
+#include "util/asset_manager.h"
#include <cstring>
#include <vector>
@@ -31,9 +30,6 @@ static int get_free_pool_slot() {
if (!g_spec_pool[i].active)
return i;
}
- // If no free slot, find one where the synth voice is inactive
- // (In a real implementation, we'd check if any voice is still using this)
- // For now, just wrap around or return -1
return -1;
}
@@ -45,10 +41,8 @@ void tracker_update(float time_sec) {
if (trigger.time_sec > time_sec)
break;
- // Trigger pattern!
const TrackerPattern& pattern = g_tracker_patterns[trigger.pattern_id];
- // Generate spectrogram for the pattern
int dest_num_frames = 0;
std::vector<float> pattern_data;
@@ -56,39 +50,54 @@ void tracker_update(float time_sec) {
for (uint32_t i = 0; i < pattern.num_events; ++i) {
const TrackerEvent& event = pattern.events[i];
- const NoteParams& params = g_tracker_samples[event.sample_id];
-
+
+ std::vector<float> note_data;
int note_frames = 0;
- std::vector<float> note_data =
- generate_note_spectrogram(params, &note_frames);
- int frame_offset = (int)(event.beat * beat_to_sec * 32000.0f / DCT_SIZE);
- paste_spectrogram(pattern_data, &dest_num_frames, note_data, note_frames,
- frame_offset);
- }
+ AssetId aid = g_tracker_sample_assets[event.sample_id];
+ if (aid != AssetId::ASSET_LAST_ID) {
+ size_t size;
+ const uint8_t* data = GetAsset(aid, &size);
+ if (data && size >= sizeof(SpecHeader)) {
+ const SpecHeader* header = (const SpecHeader*)data;
+ note_frames = header->num_frames;
+ const float* src_spectral_data = (const float*)(data + sizeof(SpecHeader));
+ note_data.assign(src_spectral_data, src_spectral_data + (size_t)note_frames * DCT_SIZE);
+ }
+ } else {
+ const NoteParams& params = g_tracker_samples[event.sample_id];
+ note_data = generate_note_spectrogram(params, &note_frames);
+ }
- // Register with synth
- int slot = get_free_pool_slot();
- if (slot != -1) {
- // Clean up old if needed
- if (g_spec_pool[slot].synth_id != -1) {
- synth_unregister_spectrogram(g_spec_pool[slot].synth_id);
- delete[] g_spec_pool[slot].data;
+ if (note_frames > 0) {
+ int frame_offset = (int)(event.beat * beat_to_sec * 32000.0f / DCT_SIZE);
+ paste_spectrogram(pattern_data, &dest_num_frames, note_data, note_frames,
+ frame_offset);
}
+ }
+
+ if (dest_num_frames > 0) {
+ int slot = get_free_pool_slot();
+ if (slot != -1) {
+ if (g_spec_pool[slot].synth_id != -1) {
+ synth_unregister_spectrogram(g_spec_pool[slot].synth_id);
+ delete[] g_spec_pool[slot].data;
+ }
- g_spec_pool[slot].data = new float[pattern_data.size()];
- memcpy(g_spec_pool[slot].data, pattern_data.data(),
- pattern_data.size() * sizeof(float));
+ g_spec_pool[slot].data = new float[pattern_data.size()];
+ memcpy(g_spec_pool[slot].data, pattern_data.data(),
+ pattern_data.size() * sizeof(float));
- Spectrogram spec;
- spec.spectral_data_a = g_spec_pool[slot].data;
- spec.spectral_data_b = g_spec_pool[slot].data;
- spec.num_frames = dest_num_frames;
+ Spectrogram spec;
+ spec.spectral_data_a = g_spec_pool[slot].data;
+ spec.spectral_data_b = g_spec_pool[slot].data;
+ spec.num_frames = dest_num_frames;
- g_spec_pool[slot].synth_id = synth_register_spectrogram(&spec);
- g_spec_pool[slot].active = true;
+ g_spec_pool[slot].synth_id = synth_register_spectrogram(&spec);
+ g_spec_pool[slot].active = true;
- synth_trigger_voice(g_spec_pool[slot].synth_id, 1.0f, 0.0f);
+ synth_trigger_voice(g_spec_pool[slot].synth_id, 1.0f, 0.0f);
+ }
}
g_last_trigger_idx++;