- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
- #include <SDL2/SDL.h>
- #include <acm/libacm.h>
- /* Written circa 2014 by grepwood@sucs.org */
- /* This program will utilize libacm and some string logic
- * in order to absolutely correctly decode an ACM at all times,
- * without user hints. */
- /* prototype for our audio callback
- * see the implementation for more information */
- /* variable declarations */
- static uint8_t *audio_pos; /* global pointer to the audio buffer to be played */
- static uint32_t audio_len; /* remaining length of the sample we have to play */
- /* audio callback function
- * here you have to copy the data of your audio buffer into the
- * requesting audio buffer (stream)
- * you should only copy as much as the requested length (len) */
- void my_audio_callback(void * userdata, Uint8 *stream, int len) {
- if (audio_len ==0)
- return;
- len = ( (unsigned)len > audio_len ? audio_len : (unsigned)len );
- SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME); /* mix from one buffer into another */
- audio_pos += len;
- audio_len -= len;
- }
- /* Some sounds in Fallout have spoofed channel amount.
- * Known suspects are from the Speech directory.
- * Hence the strstr call */
- uint8_t DetectFakeStereo(const char *fn) {
- uint8_t result = 0;
- char * pointer;
- pointer = strstr(fn,"Speech");
- if(pointer != NULL) {
- result = 1;
- }
- return result;
- }
- int main(int argc, char* argv[]){
- static uint32_t wav_length;
- static uint8_t *wav_buffer;
- static SDL_AudioSpec wav_spec;
- uint32_t wavsize;
- char * fn2 = NULL;
- uint8_t cf_force_chans;
- SDL_RWops * WavFromACM = NULL;
- if ( argc != 2 ) {
- fputs("Need a path to ACM file\n",stderr);
- return 2;
- }
- if (SDL_Init(SDL_INIT_AUDIO) < 0) {
- fputs("Could not SDL_Init\n",stderr);
- return 1;
- }
- /* Detect spoofed stereo by known strings */
- cf_force_chans = DetectFakeStereo(argv[1]);
- /* FSF.ACM is unfortunately spoofed too */
- cf_force_chans = 1;
- /* Convert the ACM to WAV */
- fn2 = libacm_decode_file_to_mem(argv[1],cf_force_chans,&wavsize);
- /* Load the WAV the specs, length and buffer of our wav are filled */
- WavFromACM = SDL_RWFromConstMem(fn2,wavsize);
- if(SDL_LoadWAV_RW(WavFromACM,1,&wav_spec,&wav_buffer, &wav_length) == NULL) {
- free(fn2);
- fputs("Loading the ACM didn't succeed\n",stderr);
- return 2;
- }
- /* set the callback function */
- wav_spec.callback = my_audio_callback;
- wav_spec.userdata = NULL;
- /* set our global static variables */
- audio_pos = wav_buffer; /* copy sound buffer */
- audio_len = wav_length; /* copy file length */
- /* Open the audio device */
- if ( SDL_OpenAudio(&wav_spec, NULL) < 0 ){
- fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
- free(fn2);
- exit(-1);
- }
- /* Start playing */
- SDL_PauseAudio(0);
- /* wait until we're don't playing */
- while ( audio_len > 0 ) {
- SDL_Delay(100);
- }
- /* shut everything down */
- SDL_CloseAudio();
- SDL_FreeWAV(wav_buffer);
- free(fn2);
- return 0;
- }
You must be logged in to paste new items to the PasteBin