diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8eff2a4a6..6e3628618 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.14)
 
-project(libscratchcpp VERSION 0.13.2 LANGUAGES C CXX)
+project(libscratchcpp VERSION 0.13.3 LANGUAGES C CXX)
 
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 set(CMAKE_CXX_STANDARD 17)
diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt
index f3319207d..72d98eb76 100644
--- a/src/audio/CMakeLists.txt
+++ b/src/audio/CMakeLists.txt
@@ -1,6 +1,6 @@
 option(LIBSCRATCHCPP_AUDIO_SUPPORT "Audio support" ON)
 
-add_library(scratchcpp-audio STATIC)
+add_library(scratchcpp-audio SHARED)
 set(MINIAUDIO_SRC internal/thirdparty/miniaudio)
 
 if (LIBSCRATCHCPP_AUDIO_SUPPORT)
@@ -11,7 +11,7 @@ if (LIBSCRATCHCPP_AUDIO_SUPPORT)
     target_include_directories(scratchcpp-audio PUBLIC ${CMAKE_CURRENT_LIST_DIR}/${MINIAUDIO_SRC})
     install(TARGETS miniaudio DESTINATION lib)
 
-    target_link_libraries(scratchcpp-audio PRIVATE miniaudio)
+    target_link_libraries(scratchcpp-audio PUBLIC miniaudio)
     target_compile_definitions(scratchcpp-audio PUBLIC LIBSCRATCHCPP_AUDIO_SUPPORT)
 endif()
 
@@ -49,3 +49,5 @@ else()
         internal/audioloudnessstub.h
     )
 endif()
+
+install(TARGETS scratchcpp-audio DESTINATION lib)
diff --git a/src/audio/audioinput.cpp b/src/audio/audioinput.cpp
index 38f1c263b..1d7b87529 100644
--- a/src/audio/audioinput.cpp
+++ b/src/audio/audioinput.cpp
@@ -10,7 +10,7 @@
 
 using namespace libscratchcpp;
 
-std::shared_ptr<IAudioInput> AudioInput::m_instance = std::make_shared<AudioInput>();
+static std::shared_ptr<IAudioInput> INSTANCE = std::make_shared<AudioInput>();
 
 AudioInput::AudioInput()
 {
@@ -18,7 +18,7 @@ AudioInput::AudioInput()
 
 std::shared_ptr<IAudioInput> AudioInput::instance()
 {
-    return m_instance;
+    return INSTANCE;
 }
 
 std::shared_ptr<IAudioLoudness> AudioInput::audioLoudness() const
diff --git a/src/audio/audioinput.h b/src/audio/audioinput.h
index 527dc6626..7d59e6e6f 100644
--- a/src/audio/audioinput.h
+++ b/src/audio/audioinput.h
@@ -19,8 +19,6 @@ class AudioInput : public IAudioInput
         std::shared_ptr<IAudioLoudness> audioLoudness() const override;
 
     private:
-        static std::shared_ptr<IAudioInput> m_instance;
-
         mutable std::shared_ptr<IAudioLoudness> m_audioLoudness;
 };
 
diff --git a/src/audio/audiooutput.cpp b/src/audio/audiooutput.cpp
index c7f15d4c7..96e1c9e76 100644
--- a/src/audio/audiooutput.cpp
+++ b/src/audio/audiooutput.cpp
@@ -10,7 +10,7 @@
 
 using namespace libscratchcpp;
 
-std::shared_ptr<IAudioOutput> AudioOutput::m_instance = std::make_shared<AudioOutput>();
+static std::shared_ptr<IAudioOutput> INSTANCE = std::make_shared<AudioOutput>();
 
 AudioOutput::AudioOutput()
 {
@@ -18,7 +18,7 @@ AudioOutput::AudioOutput()
 
 std::shared_ptr<IAudioOutput> AudioOutput::instance()
 {
-    return m_instance;
+    return INSTANCE;
 }
 
 std::shared_ptr<IAudioPlayer> AudioOutput::createAudioPlayer() const
diff --git a/src/audio/audiooutput.h b/src/audio/audiooutput.h
index bb6e734bb..e331b545a 100644
--- a/src/audio/audiooutput.h
+++ b/src/audio/audiooutput.h
@@ -15,9 +15,6 @@ class AudioOutput : public IAudioOutput
         static std::shared_ptr<IAudioOutput> instance();
 
         std::shared_ptr<IAudioPlayer> createAudioPlayer() const override;
-
-    private:
-        static std::shared_ptr<IAudioOutput> m_instance;
 };
 
 } // namespace libscratchcpp
diff --git a/src/audio/internal/audioengine.cpp b/src/audio/internal/audioengine.cpp
index 1af3874d4..aa170f6c4 100644
--- a/src/audio/internal/audioengine.cpp
+++ b/src/audio/internal/audioengine.cpp
@@ -7,27 +7,27 @@
 
 using namespace libscratchcpp;
 
-AudioEngine AudioEngine::instance;
+static AudioEngine INSTANCE;
 
 IAudioEngine *IAudioEngine::instance()
 {
-    return &AudioEngine::instance;
+    return &INSTANCE;
 }
 
 ma_engine *AudioEngine::engine()
 {
-    if (!instance.m_initialized)
-        instance.init();
+    if (!INSTANCE.m_initialized)
+        INSTANCE.init();
 
-    return instance.m_initialized ? instance.m_engine : nullptr;
+    return INSTANCE.m_initialized ? INSTANCE.m_engine : nullptr;
 }
 
 bool AudioEngine::initialized()
 {
-    if (!instance.m_initialized)
-        instance.init();
+    if (!INSTANCE.m_initialized)
+        INSTANCE.init();
 
-    return instance.m_initialized;
+    return INSTANCE.m_initialized;
 }
 
 float AudioEngine::volume() const
diff --git a/src/audio/internal/audioengine.h b/src/audio/internal/audioengine.h
index 02672ff30..4b030837d 100644
--- a/src/audio/internal/audioengine.h
+++ b/src/audio/internal/audioengine.h
@@ -15,6 +15,9 @@ namespace libscratchcpp
 class AudioEngine : public IAudioEngine
 {
     public:
+        AudioEngine();
+        ~AudioEngine();
+
         friend class IAudioEngine;
 
         static ma_engine *engine();
@@ -24,13 +27,8 @@ class AudioEngine : public IAudioEngine
         void setVolume(float volume) override;
 
     private:
-        AudioEngine();
-        ~AudioEngine();
-
         void init();
 
-        static AudioEngine instance;
-
         ma_engine *m_engine = nullptr;
         bool m_initialized = false;
         float m_volume = 1.0f;
diff --git a/src/project_p.cpp b/src/project_p.cpp
index 5dd383311..bfc005ae5 100644
--- a/src/project_p.cpp
+++ b/src/project_p.cpp
@@ -76,7 +76,7 @@ bool ProjectPrivate::tryLoad(IProjectReader *reader)
 
         // Get asset file names
         std::vector<std::string> assetNames;
-        std::unordered_map<std::string, Asset *> assets;
+        std::unordered_map<std::string, std::vector<Asset *>> assets; // multiple assets can use the same file
         const auto &targets = reader->targets();
 
         for (auto target : targets) {
@@ -87,18 +87,18 @@ bool ProjectPrivate::tryLoad(IProjectReader *reader)
                 auto it = std::find(assetNames.begin(), assetNames.end(), costume->fileName());
                 if (it == assetNames.end()) {
                     assetNames.push_back(costume->fileName());
-                    assets[assetNames.back()] = costume.get();
+                    assets[assetNames.back()] = { costume.get() };
                 } else
-                    assets[*it] = costume.get();
+                    assets[*it].push_back(costume.get());
             }
 
             for (auto sound : sounds) {
                 auto it = std::find(assetNames.begin(), assetNames.end(), sound->fileName());
                 if (it == assetNames.end()) {
                     assetNames.push_back(sound->fileName());
-                    assets[assetNames.back()] = sound.get();
+                    assets[assetNames.back()] = { sound.get() };
                 } else
-                    assets[*it] = sound.get();
+                    assets[*it].push_back(sound.get());
             }
         }
 
@@ -120,10 +120,14 @@ bool ProjectPrivate::tryLoad(IProjectReader *reader)
 
         // Load asset data
         for (size_t i = 0; i < assets.size(); i++) {
-            const std::string &data = assetData[i];
-            char *ptr = (char *)malloc(data.size() * sizeof(char));
-            strncpy(ptr, data.data(), data.size());
-            assets[assetNames[i]]->setData(data.size(), ptr);
+            const std::vector<Asset *> &assetList = assets[assetNames[i]];
+
+            for (Asset *asset : assetList) {
+                const std::string &data = assetData[i];
+                char *ptr = (char *)malloc(data.size() * sizeof(char));
+                memcpy(ptr, data.data(), data.size() * sizeof(char));
+                asset->setData(data.size(), ptr);
+            }
         }
 
     } else {
