Untitled
unknown
plain_text
9 months ago
6.1 kB
5
Indexable
// Resource state tracking
typedef enum {
RESOURCE_STATE_UNLOADED,
RESOURCE_STATE_LOADING,
RESOURCE_STATE_READY,
RESOURCE_STATE_ERROR
} ResourceState;
// Enhanced audio resource structure
typedef struct {
kresource_audio base_resource;
ResourceState state;
// Streaming specifics
stb_vorbis* vorbis_handle;
ALuint streaming_buffers[OPENAL_BACKEND_STREAM_MAX_BUFFER_COUNT];
u64 total_samples_left;
u64 current_stream_position;
// Error tracking
char error_message[256];
// Reference counting
u32 ref_count;
b8 is_stream;
} EnhancedAudioResource;
// Resource pool management
typedef struct {
EnhancedAudioResource* resources;
u32 max_resources;
smutex resource_mutex;
u32* free_handles;
u32 free_handle_count;
} ResourcePool;
// Global resource pool
static ResourcePool g_resource_pool;
// Initialize resource pool
b8 initialize_resource_pool(u32 max_resources) {
g_resource_pool.resources = sallocate(
sizeof(EnhancedAudioResource) * max_resources,
MEMORY_TAG_AUDIO
);
g_resource_pool.max_resources = max_resources;
g_resource_pool.free_handles = sallocate(
sizeof(u32) * max_resources,
MEMORY_TAG_AUDIO
);
// Initialize free handles
for (u32 i = 0; i < max_resources; i++) {
g_resource_pool.free_handles[i] = i;
}
g_resource_pool.free_handle_count = max_resources;
smutex_create(&g_resource_pool.resource_mutex);
return true;
}
// Allocate a resource handle
khandle allocate_resource_handle() {
smutex_lock(&g_resource_pool.resource_mutex);
if (g_resource_pool.free_handle_count == 0) {
smutex_unlock(&g_resource_pool.resource_mutex);
KERROR("No free resource handles available");
return INVALID_KHANDLE;
}
khandle handle = g_resource_pool.free_handles[--g_resource_pool.free_handle_count];
smutex_unlock(&g_resource_pool.resource_mutex);
return handle;
}
// Enhanced resource loading with error tracking
b8 enhanced_resource_load(const char* filepath, b8 is_stream, khandle resource_handle) {
if (resource_handle == INVALID_KHANDLE) {
KERROR("Invalid resource handle");
return false;
}
smutex_lock(&g_resource_pool.resource_mutex);
EnhancedAudioResource* resource = &g_resource_pool.resources[resource_handle];
// Reset resource state
memset(resource, 0, sizeof(EnhancedAudioResource));
resource->state = RESOURCE_STATE_LOADING;
resource->is_stream = is_stream;
// Open Vorbis stream
int error;
resource->vorbis_handle = stb_vorbis_open_filename(filepath, &error, NULL);
if (!resource->vorbis_handle) {
snprintf(resource->error_message, sizeof(resource->error_message),
"Vorbis stream open failed: %d", error);
resource->state = RESOURCE_STATE_ERROR;
smutex_unlock(&g_resource_pool.resource_mutex);
return false;
}
// Generate streaming buffers if needed
if (is_stream) {
alGenBuffers(OPENAL_BACKEND_STREAM_MAX_BUFFER_COUNT, resource->streaming_buffers);
}
// Prepare streaming metadata
stb_vorbis_info info = stb_vorbis_get_info(resource->vorbis_handle);
resource->total_samples_left = stb_vorbis_stream_length_in_samples(resource->vorbis_handle);
resource->state = RESOURCE_STATE_READY;
resource->ref_count = 1;
smutex_unlock(&g_resource_pool.resource_mutex);
return true;
}
// Enhanced stream update with error handling
b8 enhanced_stream_update(kaudio_plugin_source* source) {
EnhancedAudioResource* resource = source->current;
if (!resource || resource->state != RESOURCE_STATE_READY) {
return false;
}
// Streaming logic with error handling
ALint processed_buffers = 0;
alGetSourcei(source->id, AL_BUFFERS_PROCESSED, &processed_buffers);
while (processed_buffers--) {
ALuint buffer;
alSourceUnqueueBuffers(source->id, 1, &buffer);
// Stream more data
short stream_buffer[4096];
int samples_read = stb_vorbis_get_samples_short_interleaved(
resource->vorbis_handle,
2, // Assuming stereo
stream_buffer,
sizeof(stream_buffer) / sizeof(short)
);
if (samples_read == 0) {
if (resource->is_stream) {
stb_vorbis_seek_start(resource->vorbis_handle);
samples_read = stb_vorbis_get_samples_short_interleaved(
resource->vorbis_handle,
2,
stream_buffer,
sizeof(stream_buffer) / sizeof(short)
);
} else {
return false; // End of stream
}
}
alBufferData(buffer, AL_FORMAT_STEREO16,
stream_buffer,
samples_read * sizeof(short) * 2,
44100); // Assuming 44.1kHz
alSourceQueueBuffers(source->id, 1, &buffer);
}
return true;
}
// Resource cleanup
void cleanup_audio_resource(khandle resource_handle) {
smutex_lock(&g_resource_pool.resource_mutex);
EnhancedAudioResource* resource = &g_resource_pool.resources[resource_handle];
if (resource->ref_count > 0) {
resource->ref_count--;
}
if (resource->ref_count == 0) {
// Free OpenAL buffers
if (resource->is_stream) {
alDeleteBuffers(OPENAL_BACKEND_STREAM_MAX_BUFFER_COUNT, resource->streaming_buffers);
}
// Close Vorbis handle
if (resource->vorbis_handle) {
stb_vorbis_close(resource->vorbis_handle);
}
// Return handle to pool
g_resource_pool.free_handles[g_resource_pool.free_handle_count++] = resource_handle;
// Reset resource state
memset(resource, 0, sizeof(EnhancedAudioResource));
}
smutex_unlock(&g_resource_pool.resource_mutex);
}Editor is loading...
Leave a Comment