Skip to content

Instantly share code, notes, and snippets.

@grepwood
Created September 28, 2014 18:17
Show Gist options
  • Save grepwood/31dcb3219b281a8e00c1 to your computer and use it in GitHub Desktop.
Save grepwood/31dcb3219b281a8e00c1 to your computer and use it in GitHub Desktop.
Plays Interplay's ACM files in SDL2
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <dataio/BigEndian.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 = ( len > audio_len ? audio_len : len );
//SDL_memcpy (stream, audio_pos, len); // simply copy from one buffer into the other
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);// mix from one buffer into another
audio_pos += len;
audio_len -= len;
}
char * decode_file_mem(const char *fn, unsigned * wavsize);
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;
SDL_RWops * WavFromACM;
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
return 1;
}
/* Convert the ACM to WAV */
fn2 = decode_file_mem(argv[1],&wavsize);
WavFromACM = SDL_RWFromConstMem(fn2,wavsize);
/* Load the WAV
the specs, length and buffer of our wav are filled
*/ if(SDL_LoadWAV_RW(WavFromACM,1,&wav_spec,&wav_buffer, &wav_length) == NULL) {
free(fn2);
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);
FILE * dotwav = fopen("HAKUN.wav","wb");
fwrite(fn2,wavsize,1,dotwav);
fclose(dotwav);
free(fn2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment