|
@@ -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)
|
|
{
|
|
{
|