 
     image: (msg, callback) ->
       [_, path] = msg
-      get_image_data path, (image_bytes, width, height) ->
-        if !image_bytes
-          callback ["error", "Failed to find image: #{path}"]
+      @file_loader.get_file path, "image", (img) ->
+        if img?
+          [img, w, h] = img
+          callback ["success", img, w, h]
         else
-          callback ["success", image_bytes, width, height]
+          ["error", "Failed to find image: #{path}"]
 
     audio: (msg, callback) ->
       [_, path, type] = msg
-      @audio.new_source path, type, (source_id) ->
+
+      file_type = switch type
+        when "static" then "sound"
+        when "streaming" then "music"
+        else throw "Unknown source type: #{type}"
+
+      @file_loader.get_file path, file_type, (source_id) ->
         if source_id isnt null
           callback ["success", source_id]
         else

class Aroma.Audio
  constructor: ->
    @sources = []
    @url_to_source = {}
    @context = new webkitAudioContext

  stop_all: ->

    [str, bytestring, real_width, @height]


# Loads and caches files
class Aroma.FileLoader
  loaders: {
    sound: (path, callback) ->
      audio = @aroma.audio
      StaticSource.from_url audio.context, path, (source) =>
        callback audio.add_source source

    music: (path, callback) ->
      StreamingSource.from_url path, (source) =>
        callback @aroma.audio.add_source source

    image: (path, callback) ->
      get_image_data path, (image_bytes, width, height) ->
        return callback [image_bytes, width, height] if image_bytes?
        callback null
  }

  default_loader: (path, callback) ->
