Untitled

 avatar
unknown
plain_text
18 days ago
6.1 kB
3
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