浏览代码

LoadMusicStreamFromMemory (#1606)

* define SUPPORT_FILEFORMAT_MOD in config.h

* RLAPI LoadModuleFromData() definition in raylib.h

* LoadModuleFromData() definition in raudio.h

* LoadModuleFromData implementation in raudio.c

* Rename API to LoadMusicStreamFromMemory & default unload.

* raudio.c tabs to spaces

* Styling curly bracket and removing dev debugging TRACELOG

Co-authored-by: nezvers <[email protected]>
Agnis "NeZvērs" Aldiņš 4 年之前
父节点
当前提交
209445ccde
共有 4 个文件被更改,包括 100 次插入1 次删除
  1. 1 1
      src/config.h
  2. 97 0
      src/raudio.c
  3. 1 0
      src/raudio.h
  4. 1 0
      src/raylib.h

+ 1 - 1
src/config.h

@@ -187,7 +187,7 @@
 #define SUPPORT_FILEFORMAT_WAV      1
 #define SUPPORT_FILEFORMAT_WAV      1
 #define SUPPORT_FILEFORMAT_OGG      1
 #define SUPPORT_FILEFORMAT_OGG      1
 #define SUPPORT_FILEFORMAT_XM       1
 #define SUPPORT_FILEFORMAT_XM       1
-//#define SUPPORT_FILEFORMAT_MOD      1
+#define SUPPORT_FILEFORMAT_MOD      1
 #define SUPPORT_FILEFORMAT_MP3      1
 #define SUPPORT_FILEFORMAT_MP3      1
 //#define SUPPORT_FILEFORMAT_FLAC     1
 //#define SUPPORT_FILEFORMAT_FLAC     1
 
 

+ 97 - 0
src/raudio.c

@@ -1297,6 +1297,103 @@ Music LoadMusicStream(const char *fileName)
     return music;
     return music;
 }
 }
 
 
+// extension including period ".mod"
+Music LoadMusicStreamFromMemory(const char *fileType, unsigned char* data, int dataSize)
+{
+    Music music = { 0 };
+    bool musicLoaded = false;
+    
+    char fileExtLower[16] = { 0 };
+    strcpy(fileExtLower, TextToLower(fileType));
+    
+    if (false) { }
+#if defined(SUPPORT_FILEFORMAT_XM)
+    if (TextIsEqual(fileExtLower, ".xm"))
+    {
+        jar_xm_context_t *ctxXm = NULL;
+        int result = jar_xm_create_context_safe(&ctxXm, data, dataSize, 48000);
+        if (result == 0)    // XM AUDIO.System.context created successfully
+        {
+            music.ctxType = MUSIC_MODULE_XM;
+            jar_xm_set_max_loop_count(ctxXm, 0);    // Set infinite number of loops
+
+            // NOTE: Only stereo is supported for XM
+            music.stream = InitAudioStream(48000, 16, 2);
+            music.sampleCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm)*2;    // 2 channels
+            music.looping = true;   // Looping enabled by default
+            jar_xm_reset(ctxXm);   // make sure we start at the beginning of the song
+
+            music.ctxData = ctxXm;
+            musicLoaded = true;
+        }
+    }
+#endif
+#if defined(SUPPORT_FILEFORMAT_MOD)
+    else if (TextIsEqual(fileExtLower, ".mod"))
+    {
+        jar_mod_context_t *ctxMod = RL_MALLOC(sizeof(jar_mod_context_t));
+        int result = 0;
+
+        jar_mod_init(ctxMod);
+        
+        // copy data to allocated memory for default UnloadMusicStream
+        unsigned char *newData = RL_MALLOC(dataSize);
+        int it = dataSize / sizeof(unsigned char);
+        for (int i = 0; i < it; i++){
+            newData[i] = data[i];
+        }
+        
+        // Memory loaded version for jar_mod_load_file()
+        if (dataSize && dataSize < 32*1024*1024)
+        {
+            ctxMod->modfilesize = dataSize;
+            ctxMod->modfile = newData;
+            if(jar_mod_load(ctxMod, (void*)ctxMod->modfile, dataSize)) result = dataSize;
+        }
+        
+        if (result > 0)
+        {
+            music.ctxType = MUSIC_MODULE_MOD;
+
+            // NOTE: Only stereo is supported for MOD
+            music.stream = InitAudioStream(48000, 16, 2);
+            music.sampleCount = (unsigned int)jar_mod_max_samples(ctxMod)*2;    // 2 channels
+            music.looping = true;   // Looping enabled by default
+            musicLoaded = true;
+
+            music.ctxData = ctxMod;
+            musicLoaded = true;
+        }
+    }
+#endif 
+    else TRACELOG(LOG_WARNING, "STREAM: [%s] Fileformat not supported", fileType);
+
+    if (!musicLoaded)
+    {
+        if (false) { }
+    #if defined(SUPPORT_FILEFORMAT_XM)
+        else if (music.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)music.ctxData);
+    #endif
+    #if defined(SUPPORT_FILEFORMAT_MOD)
+        else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); }
+    #endif
+
+        music.ctxData = NULL;
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Music memory could not be opened", fileType);
+    }
+    else
+    {
+        // Show some music stream info
+        TRACELOG(LOG_INFO, "FILEIO: [%s] Music memory successfully loaded:", fileType);
+        TRACELOG(LOG_INFO, "    > Total samples: %i", music.sampleCount);
+        TRACELOG(LOG_INFO, "    > Sample rate:   %i Hz", music.stream.sampleRate);
+        TRACELOG(LOG_INFO, "    > Sample size:   %i bits", music.stream.sampleSize);
+        TRACELOG(LOG_INFO, "    > Channels:      %i (%s)", music.stream.channels, (music.stream.channels == 1)? "Mono" : (music.stream.channels == 2)? "Stereo" : "Multi");
+    }
+
+    return music;
+}
+
 // Unload music stream
 // Unload music stream
 void UnloadMusicStream(Music music)
 void UnloadMusicStream(Music music)
 {
 {

+ 1 - 0
src/raudio.h

@@ -164,6 +164,7 @@ float *GetWaveData(Wave wave);                                  // Get samples d
 
 
 // Music management functions
 // Music management functions
 Music LoadMusicStream(const char *fileName);                    // Load music stream from file
 Music LoadMusicStream(const char *fileName);                    // Load music stream from file
+Music LoadMusicStreamFromMemory(const char *fileType, unsigned char* data, int dataSize); // Load module music from data
 void UnloadMusicStream(Music music);                            // Unload music stream
 void UnloadMusicStream(Music music);                            // Unload music stream
 void PlayMusicStream(Music music);                              // Start music playing
 void PlayMusicStream(Music music);                              // Start music playing
 void UpdateMusicStream(Music music);                            // Updates buffers for music streaming
 void UpdateMusicStream(Music music);                            // Updates buffers for music streaming

+ 1 - 0
src/raylib.h

@@ -1495,6 +1495,7 @@ RLAPI void UnloadWaveSamples(float *samples);                         // Unload
 
 
 // Music management functions
 // Music management functions
 RLAPI Music LoadMusicStream(const char *fileName);                    // Load music stream from file
 RLAPI Music LoadMusicStream(const char *fileName);                    // Load music stream from file
+RLAPI Music LoadMusicStreamFromMemory(const char *fileType, unsigned char* data, int dataSize); // Load module music from data
 RLAPI void UnloadMusicStream(Music music);                            // Unload music stream
 RLAPI void UnloadMusicStream(Music music);                            // Unload music stream
 RLAPI void PlayMusicStream(Music music);                              // Start music playing
 RLAPI void PlayMusicStream(Music music);                              // Start music playing
 RLAPI void UpdateMusicStream(Music music);                            // Updates buffers for music streaming
 RLAPI void UpdateMusicStream(Music music);                            // Updates buffers for music streaming