diff --git a/REDALERT/AUDIOMIX.H b/REDALERT/AUDIOMIX.H index 0192601..37603c9 100644 --- a/REDALERT/AUDIOMIX.H +++ b/REDALERT/AUDIOMIX.H @@ -8,4 +8,6 @@ void AudMix_Init(void); const char* GetEffectFileName(int index); const char* GetThemeMusicFileName(int index); void AudMix_PlayMusic(int musicId); -const char* GetSpeechFileName(int index); \ No newline at end of file +const char* GetSpeechFileName(int index); +void AudMix_QueueVideoAudio(const char* audio_buffer, int length, int rate); +void AudMix_TickMovieAudio(void); \ No newline at end of file diff --git a/REDALERT/AUDMIX.CPP b/REDALERT/AUDMIX.CPP index becd94a..1602858 100644 --- a/REDALERT/AUDMIX.CPP +++ b/REDALERT/AUDMIX.CPP @@ -31,10 +31,12 @@ enum AudioBufferType_t { }; #define MAX_PRECACHE_AUDIO 512 +#define MAX_STREAM_BUFFERS 20 AudioBuffer_t precacheAudioTable[AUDIO_BUFFER_NUMTYPES][MAX_PRECACHE_AUDIO]; AudioBuffer_t speechPrecacheAudioTable[MAX_PRECACHE_AUDIO]; AudioBuffer_t musicPrecacheAudioTable[MAX_PRECACHE_AUDIO]; +ALuint streaming_buffers[MAX_STREAM_BUFFERS]; int currentMusicPlaying = -1; int currentAudioTSource = 0; @@ -62,7 +64,9 @@ struct WAVE_Data { }; #define MAX_AUDIO_SOURCES 32 +#define MOVIE_AUDIO_SOURCE (MAX_AUDIO_SOURCES - 2) ALuint audio_sources[MAX_AUDIO_SOURCES]; +int current_streaming_audiosource = 0; bool loadWavFile(const char* filename, AudioBuffer_t &audioBuffer) { FILE* soundFile = NULL; @@ -175,6 +179,59 @@ void AudMix_PlayMusic(int musicId) { currentMusicPlaying = musicId; } +bool AudMix_IsSourcePlaying(ALuint source) +{ + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return (state == AL_PLAYING); +} + +void AudMix_TickMovieAudio(void) { + int numBuffers = 0; + + alGetSourcei(audio_sources[MOVIE_AUDIO_SOURCE], AL_BUFFERS_PROCESSED, &numBuffers); + while (numBuffers--) + { + ALuint buffer; + alSourceUnqueueBuffers(audio_sources[MOVIE_AUDIO_SOURCE], 1, &buffer); + } +} + +/* +============= +AudMix_QueueVideoAudio +============= +*/ +void AudMix_QueueVideoAudio(const char* audio_buffer, int length, int rate) { + int numBuffers = 0; + + alGetSourcei(audio_sources[MOVIE_AUDIO_SOURCE], AL_BUFFERS_PROCESSED, &numBuffers); + while (numBuffers--) + { + ALuint buffer; + alSourceUnqueueBuffers(audio_sources[MOVIE_AUDIO_SOURCE], 1, &buffer); + } + + numBuffers = 0; + alGetSourcei(audio_sources[MOVIE_AUDIO_SOURCE], AL_BUFFERS_QUEUED, &numBuffers); + if (numBuffers == MAX_STREAM_BUFFERS) + { + // assert(!"Steam dropping raw samples, reached MAX_STREAM_BUFFERS"); + return; + } + + if (current_streaming_audiosource >= MAX_STREAM_BUFFERS) + current_streaming_audiosource = 0; + + alBufferData(streaming_buffers[current_streaming_audiosource], AL_FORMAT_MONO16, (ALvoid*)audio_buffer, length, 22050); + alSourceQueueBuffers(audio_sources[MOVIE_AUDIO_SOURCE], 1, &streaming_buffers[current_streaming_audiosource]); + if(!AudMix_IsSourcePlaying(audio_sources[MOVIE_AUDIO_SOURCE])) + alSourcePlay(audio_sources[MOVIE_AUDIO_SOURCE]); + + //MOVIE_AUDIO_SOURCE + current_streaming_audiosource++; +} + /* ============= AudMix_Init @@ -238,10 +295,12 @@ void AudMix_Init(void) { alSource3f(audio_sources[i], AL_POSITION, 0.0f, 0.0f, 0.0f); alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); + + alGenBuffers(MAX_STREAM_BUFFERS, streaming_buffers); } void PlayAudio(AudioBuffer_t& buffer) { - if (currentAudioTSource >= MAX_AUDIO_SOURCES - 1) + if (currentAudioTSource >= MAX_AUDIO_SOURCES - 2) currentAudioTSource = 0; alSourcei(audio_sources[currentAudioTSource], AL_BUFFER, buffer.buffer); diff --git a/REDALERT/VQAMOVIE.CPP b/REDALERT/VQAMOVIE.CPP index 06d2d69..b83f807 100644 --- a/REDALERT/VQAMOVIE.CPP +++ b/REDALERT/VQAMOVIE.CPP @@ -3,7 +3,9 @@ #include "FUNCTION.H" #include "VQAMOVIE.H" +#include "AUDIOMIX.H" #include +#include byte* raw_image_buffer = nullptr; int vqa_upscale_hack_width = 0; @@ -77,7 +79,8 @@ long VQA_Open(_VQAHandle *videoHandle, char const* filename) { double usf; smk_info_video(videoHandle->smacker_video, &videoHandle->width, &videoHandle->height, &yscalemode); smk_info_all(videoHandle->smacker_video, &frame, &videoHandle->frame_count, &usf); - smk_enable_video(videoHandle->smacker_video, 1); + smk_enable_all(videoHandle->smacker_video, 65536); + smk_info_audio(videoHandle->smacker_video, &videoHandle->track_mask, &videoHandle->channels[0], &videoHandle->bitdepth[0], &videoHandle->audio_rate[0]); videoHandle->video_graphics_buffer = &VisiblePage;//new GraphicBufferClass(); if (vqa_output_buffer == nullptr) vqa_output_buffer = new byte[ScreenWidth * ScreenHeight * 3]; @@ -95,7 +98,9 @@ void VQA_Close(_VQAHandle* vqaHandle) { } long VQA_Play(_VQAHandle* vqaHandle) { + int curTime = clock(); //get the current time int currentFrame = 0; + bool shouldSampleAudio = true; smk_first(vqaHandle->smacker_video); @@ -113,7 +118,14 @@ long VQA_Play(_VQAHandle* vqaHandle) { smk_render_frame(vqaHandle->smacker_video, currentFrame); + if (shouldSampleAudio) { + unsigned char* audio_track = smk_get_audio(vqaHandle->smacker_video, 0); + int audio_track_len = smk_get_audio_size(vqaHandle->smacker_video, 0); + AudMix_QueueVideoAudio((const char*)audio_track, audio_track_len, vqaHandle->audio_rate[0]); + + shouldSampleAudio = false; + } //// Grab the frame from the movie. //VQA_ImageForTime(vqaHandle, Sys_Milliseconds() - vqaHandle->startTime); // @@ -131,9 +143,14 @@ long VQA_Play(_VQAHandle* vqaHandle) { Buffer_To_Page(0, 0, ScreenWidth, ScreenHeight, vqa_output_buffer, *vqaHandle->video_graphics_buffer); vqaHandle->video_graphics_buffer->Unlock(); + + if (clock() - curTime >= 30) { + currentFrame++; + curTime = clock(); + + shouldSampleAudio = true; + } - currentFrame++; - Sleep(30); } //delete raw_image_buffer; diff --git a/REDALERT/VQAMOVIE.H b/REDALERT/VQAMOVIE.H index fda8688..945a915 100644 --- a/REDALERT/VQAMOVIE.H +++ b/REDALERT/VQAMOVIE.H @@ -26,6 +26,10 @@ struct _VQAHandle { unsigned long width; unsigned long height; unsigned long frame_count; + unsigned char track_mask; + unsigned char channels[7]; + unsigned char bitdepth[7]; + unsigned long audio_rate[7]; smk smacker_video; }; diff --git a/external/libsmacker/smacker.c b/external/libsmacker/smacker.c index 62621b3..07cc6bd 100644 --- a/external/libsmacker/smacker.c +++ b/external/libsmacker/smacker.c @@ -653,13 +653,13 @@ char smk_enable_all(smk object, const unsigned char mask) smk_null_check(object); smk_null_check(object->video); - object->video->enable = (mask & 0x80); + object->video->enable = 1; //(mask & 0x80); for (i = 0; i < 7; i ++) { if (object->audio[i]) { - object->audio[i]->enable = (mask & (0x01 << i)); + object->audio[i]->enable = 1; //(mask & (0x01 << i)); } }