Added proto version of jar_xm

This is an early draft, needs lots of work. Still need to figure out way
to calculate total length of song. This is hard because xm tracks stream
out zeros when done, only position in track can be found. Position does
not give any direct value of how much more time is left. I think that by
setting the loop count to 1 and seeking until the end I can total up the
number of samples and come up with a length.
This commit is contained in:
Joshua Reisenauer 2016-04-24 15:25:48 -07:00
parent 173529e048
commit ec2cbaa5eb
2 changed files with 2712 additions and 16 deletions

View file

@ -42,6 +42,8 @@
#include <string.h> // Required for strcmp() #include <string.h> // Required for strcmp()
#include <stdio.h> // Used for .WAV loading #include <stdio.h> // Used for .WAV loading
#include "jar_xm.h" // For playing .xm files
#if defined(AUDIO_STANDALONE) #if defined(AUDIO_STANDALONE)
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog()) #include <stdarg.h> // Used for functions with variable number of parameters (TraceLog())
#else #else
@ -73,6 +75,7 @@
// NOTE: Anything longer than ~10 seconds should be streamed... // NOTE: Anything longer than ~10 seconds should be streamed...
typedef struct Music { typedef struct Music {
stb_vorbis *stream; stb_vorbis *stream;
jar_xm_context_t *chipctx; // Stores jar_xm context
ALuint buffers[MUSIC_STREAM_BUFFERS]; ALuint buffers[MUSIC_STREAM_BUFFERS];
ALuint source; ALuint source;
@ -82,7 +85,7 @@ typedef struct Music {
int sampleRate; int sampleRate;
int totalSamplesLeft; int totalSamplesLeft;
bool loop; bool loop;
bool chipTune; // True if chiptune is loaded
} Music; } Music;
#if defined(AUDIO_STANDALONE) #if defined(AUDIO_STANDALONE)
@ -564,6 +567,22 @@ void PlayMusicStream(char *fileName)
currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels; currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
} }
} }
else if (strcmp(GetExtension(fileName),"xm") == 0)
{
currentMusic.chipTune = true;
currentMusic.channels = 2;
currentMusic.sampleRate = 48000;
currentMusic.loop = true;
// only stereo/float is supported for xm
if(info.channels == 2 && !jar_xm_create_context_from_file(&currentMusic.chipctx, currentMusic.sampleRate, fileName))
{
currentMusic.format = AL_FORMAT_STEREO_FLOAT32;
jar_xm_set_max_loop_count(currentMusic.chipctx, 0); //infinite number of loops
//currentMusic.totalSamplesLeft = ; // Unsure of how to calculate this
musicEnabled = true;
}
}
else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName); else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
} }
@ -572,14 +591,19 @@ void StopMusicStream(void)
{ {
if (musicEnabled) if (musicEnabled)
{ {
alSourceStop(currentMusic.source); alSourceStop(currentMusic.source);
EmptyMusicStream(); // Empty music buffers
EmptyMusicStream(); // Empty music buffers alDeleteSources(1, &currentMusic.source);
alDeleteBuffers(2, currentMusic.buffers);
alDeleteSources(1, &currentMusic.source);
alDeleteBuffers(2, currentMusic.buffers); if (currentMusic.chipTune)
{
stb_vorbis_close(currentMusic.stream); jar_xm_free_context(currentMusic.chipctx);
}
else
{
stb_vorbis_close(currentMusic.stream);
}
} }
musicEnabled = false; musicEnabled = false;
@ -633,7 +657,15 @@ void SetMusicVolume(float volume)
// Get current music time length (in seconds) // Get current music time length (in seconds)
float GetMusicTimeLength(void) float GetMusicTimeLength(void)
{ {
float totalSeconds = stb_vorbis_stream_length_in_seconds(currentMusic.stream); float totalSeconds;
if (currentMusic.chipTune)
{
//totalSeconds = (float)samples; // Need to figure out how toget this
}
else
{
totalSeconds = stb_vorbis_stream_length_in_seconds(currentMusic.stream);
}
return totalSeconds; return totalSeconds;
} }
@ -641,11 +673,20 @@ float GetMusicTimeLength(void)
// Get current music time played (in seconds) // Get current music time played (in seconds)
float GetMusicTimePlayed(void) float GetMusicTimePlayed(void)
{ {
int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels; float secondsPlayed;
if (currentMusic.chipTune)
int samplesPlayed = totalSamples - currentMusic.totalSamplesLeft; {
uint64_t* samples;
float secondsPlayed = (float)samplesPlayed / (currentMusic.sampleRate * currentMusic.channels); jar_xm_get_position(currentMusic.chipctx, NULL, NULL, NULL, samples); // Unsure if this is the desired value
secondsPlayed = (float)samples;
}
else
{
int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
int samplesPlayed = totalSamples - currentMusic.totalSamplesLeft;
secondsPlayed = (float)samplesPlayed / (currentMusic.sampleRate * currentMusic.channels);
}
return secondsPlayed; return secondsPlayed;
} }
@ -668,7 +709,15 @@ static bool BufferMusicStream(ALuint buffer)
{ {
while (size < MUSIC_BUFFER_SIZE) while (size < MUSIC_BUFFER_SIZE)
{ {
streamedBytes = stb_vorbis_get_samples_short_interleaved(currentMusic.stream, currentMusic.channels, pcm + size, MUSIC_BUFFER_SIZE - size); if (currentMusic.chipTune)
{
jar_xm_generate_samples(currentMusic.chipctx, pcm + size, (MUSIC_BUFFER_SIZE - size)/2);
streamedBytes = (MUSIC_BUFFER_SIZE - size)/2; // There is no end of stream for xmfiles, once the end is reached zeros are generated for non looped chiptunes.
}
else
{
streamedBytes = stb_vorbis_get_samples_short_interleaved(currentMusic.stream, currentMusic.channels, pcm + size, MUSIC_BUFFER_SIZE - size);
}
if (streamedBytes > 0) size += (streamedBytes*currentMusic.channels); if (streamedBytes > 0) size += (streamedBytes*currentMusic.channels);
else break; else break;

2647
src/jar_xm.h Normal file

File diff suppressed because it is too large Load diff