Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
30 KB
Referenced Files
None
Subscribers
None
diff --git a/util/music-player.cpp b/util/music-player.cpp
index 93eddaa4..11f73f91 100644
--- a/util/music-player.cpp
+++ b/util/music-player.cpp
@@ -1,642 +1,489 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
#include "music-player.h"
#include "globals.h"
#include "util/debug.h"
#include <iostream>
#include "configuration.h"
#include "sound.h"
#include "dumb/include/dumb.h"
#include "gme/Music_Emu.h"
#include "exceptions/exception.h"
#include <sstream>
#ifdef USE_ALLEGRO5
#include <allegro5/allegro_audio.h>
#endif
#ifdef USE_ALLEGRO
#include "dumb/include/aldumb.h"
#include "ogg/logg.h"
#ifdef _WIN32
/* what do we need winalleg for?
* reason: ...
*/
#include <winalleg.h>
#endif
#endif
#ifdef HAVE_MP3_MPG123
#include <mpg123.h>
#endif
#ifdef HAVE_MP3_MAD
#include <mad.h>
#endif
#ifdef USE_SDL
#include "sdl/mixer/SDL_mixer.h"
#endif
namespace Util{
class MusicException: public Exception::Base {
public:
MusicException(const std::string & file, int line, const std::string & reason):
Exception::Base(file, line),
reason(reason){
}
MusicException(const MusicException & copy):
Exception::Base(copy),
reason(copy.reason){
}
virtual ~MusicException() throw(){
}
protected:
virtual const std::string getReason() const {
return reason;
}
virtual Exception::Base * copy() const {
return new MusicException(*this);
}
std::string reason;
};
static double scaleVolume(double start){
return start;
}
#ifdef USE_ALLEGRO5
const int DUMB_SAMPLES = 1024;
MusicRenderer::MusicRenderer(){
stream = al_create_audio_stream(2, DUMB_SAMPLES, Sound::FREQUENCY, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2);
if (!stream){
throw MusicException(__FILE__, __LINE__, "Could not create allegro5 audio stream");
}
queue = al_create_event_queue();
al_register_event_source(queue, al_get_audio_stream_event_source(stream));
}
void MusicRenderer::play(MusicPlayer & player){
al_attach_audio_stream_to_mixer(stream, al_get_default_mixer());
}
void MusicRenderer::pause(){
al_detach_audio_stream(stream);
}
MusicRenderer::~MusicRenderer(){
al_destroy_audio_stream(stream);
al_destroy_event_queue(queue);
}
void MusicRenderer::poll(MusicPlayer & player){
ALLEGRO_EVENT event;
while (al_get_next_event(queue, &event)){
if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) {
ALLEGRO_AUDIO_STREAM * stream = (ALLEGRO_AUDIO_STREAM *) event.any.source;
void * data = al_get_audio_stream_fragment(stream);
if (data != NULL){
player.render(data, al_get_audio_stream_length(stream));
al_set_audio_stream_fragment(stream, data);
}
}
}
}
#elif USE_SDL
MusicRenderer::MusicRenderer(){
}
void MusicRenderer::mixer(void * arg, Uint8 * stream, int bytes){
MusicPlayer * player = (MusicPlayer*) arg;
player->render(stream, bytes / 4);
}
void MusicRenderer::play(MusicPlayer & player){
Mix_HookMusic(mixer, &player);
}
void MusicRenderer::pause(){
Mix_HookMusic(NULL, NULL);
}
void MusicRenderer::poll(MusicPlayer & player){
}
MusicRenderer::~MusicRenderer(){
Mix_HookMusic(NULL, NULL);
}
#elif USE_ALLEGRO
int BUFFER_SIZE = 1 << 11;
static int ALLEGRO_MONO = 0;
static int ALLEGRO_STEREO = 1;
MusicRenderer::MusicRenderer(){
stream = play_audio_stream(BUFFER_SIZE, 16, ALLEGRO_STEREO, Sound::FREQUENCY, 255, 128);
voice_set_priority(stream->voice, 255);
}
void MusicRenderer::play(MusicPlayer & player){
voice_start(stream->voice);
}
void MusicRenderer::pause(){
voice_stop(stream->voice);
}
void MusicRenderer::poll(MusicPlayer & player){
short * buffer = (short*) get_audio_stream_buffer(stream);
if (buffer){
player.render(buffer, BUFFER_SIZE);
/* allegro wants unsigned data but gme produces signed so to convert
* signed samples to unsigned samples we have to raise each value
* by half the maximum value of a short (0xffff+1)/2 = 0x8000
*/
for (int i = 0; i < BUFFER_SIZE * 2; i++){
buffer[i] += 0x8000;
}
free_audio_stream_buffer(stream);
}
}
MusicRenderer::~MusicRenderer(){
stop_audio_stream(stream);
}
#endif
MusicPlayer::MusicPlayer():
volume(1.0),
out(new MusicRenderer()){
}
MusicPlayer::~MusicPlayer(){
}
void MusicPlayer::play(){
out->play(*this);
}
void MusicPlayer::pause(){
out->pause();
}
void MusicPlayer::poll(){
out->poll(*this);
}
static const char * typeToExtension( int i ){
switch (i){
case 0 : return ".xm";
case 1 : return ".s3m";
case 2 : return ".it";
case 3 : return ".mod";
default : return "";
}
}
-#ifdef USE_ALLEGRO
-#ifdef HAVE_OGG
-OggPlayer::OggPlayer(const char * path){
- stream = logg_get_stream(path, scaleVolume(volume) * 255, 128, 1);
- if (stream == NULL){
- throw MusicException(__FILE__, __LINE__, "Could not load ogg file");
- }
-}
-
-void OggPlayer::play(){
-}
-
-void OggPlayer::poll(){
- logg_update_stream(stream);
-}
-
-void OggPlayer::render(void * stream, int length){
-}
-
-void OggPlayer::pause(){
-}
-
-void OggPlayer::setVolume(double volume){
-}
-
-OggPlayer::~OggPlayer(){
- logg_destroy_stream(stream);
-}
-#endif /* OGG */
-
-#ifdef HAVE_MP3_MAD
- /* TODO */
-Mp3Player::Mp3Player(const char * path):
-stream(NULL){
- /* TODO */
-}
-
-void Mp3Player::play(){
- /* TODO */
-}
-
-void Mp3Player::poll(){
- /* TODO */
-}
-
-void Mp3Player::pause(){
- /* TODO */
-}
-
-void Mp3Player::setVolume(double volume){
- /* TODO */
-}
-
-Mp3Player::~Mp3Player(){
- /* TODO */
-}
-#endif /* MP3_MAD */
-
-#endif /* ALLEGRO */
-
-#ifdef USE_SDL
-#ifdef HAVE_OGG
-
-OggPlayer::OggPlayer(const char * path){
- music = Mix_LoadMUS(path);
- if (music == NULL){
- throw MusicException(__FILE__, __LINE__, "Could not load OGG file");
- }
-}
-
-void OggPlayer::play(){
- Mix_PlayMusic(music, -1);
-}
-
-void OggPlayer::render(void * data, int length){
-}
-
-void OggPlayer::poll(){
-}
-
-void OggPlayer::pause(){
- Mix_PauseMusic();
-}
-
-void OggPlayer::setVolume(double volume){
- this->volume = volume;
- Mix_VolumeMusic(volume * MIX_MAX_VOLUME);
-}
-
-OggPlayer::~OggPlayer(){
- Mix_FreeMusic(music);
-}
-
-#endif /* OGG */
-#ifdef HAVE_MP3_MAD
- /* TODO */
-Mp3Player::Mp3Player(const char * path){
- music = Mix_LoadMUS(path);
- if (music == NULL){
- throw MusicException(__FILE__, __LINE__, "Could not load MP3 file");
- }
-}
-
-void Mp3Player::play(){
- Mix_PlayMusic(music, 0);
-}
-
-void Mp3Player::poll(){
- /* TODO */
-}
-
-void Mp3Player::pause(){
- Mix_PauseMusic();
-}
-
-void Mp3Player::setVolume(double volume){
- this->volume = volume;
- Mix_VolumeMusic(volume * MIX_MAX_VOLUME);
-}
-
-Mp3Player::~Mp3Player(){
- Mix_FreeMusic(music);
-}
-#endif /* MP3_MAD */
-
-#endif /* SDL */
-
-#ifdef USE_ALLEGRO5
-#ifdef HAVE_OGG
-OggPlayer::OggPlayer(const char * path){
- /* TODO */
-}
-
-void OggPlayer::play(){
- /* TODO */
-}
-
-void OggPlayer::poll(){
- /* TODO */
-}
-
-void OggPlayer::pause(){
- /* TODO */
-}
-
-void OggPlayer::render(void * stream, int length){
-}
-
-void OggPlayer::setVolume(double volume){
- /* TODO */
-}
-
-OggPlayer::~OggPlayer(){
- /* TODO */
-}
-
-#endif
-#ifdef HAVE_MP3_MAD
- /* TODO */
-Mp3Player::Mp3Player(const char * path){
- /* TODO */
-}
-
-void Mp3Player::play(){
- /* TODO */
-}
-
-void Mp3Player::poll(){
- /* TODO */
-}
-
-void Mp3Player::pause(){
- /* TODO */
-}
-
-void Mp3Player::setVolume(double volume){
- /* TODO */
-}
-
-Mp3Player::~Mp3Player(){
- /* TODO */
-}
-#endif /* MP3_MAD */
-
-#endif
-
/* expects each sample to be 4 bytes, 2 bytes per sample * 2 channels */
DumbPlayer::DumbPlayer(const char * path){
music_file = loadDumbFile(path);
if (music_file == NULL){
std::ostringstream error;
error << "Could not load DUMB file " << path;
throw MusicException(__FILE__, __LINE__, error.str());
}
int n_channels = 2;
int position = 0;
renderer = duh_start_sigrenderer(music_file, 0, n_channels, position);
if (!renderer){
Global::debug(0) << "Could not create renderer" << std::endl;
throw Exception::Base(__FILE__, __LINE__);
}
}
void DumbPlayer::render(void * data, int samples){
double delta = 65536.0 / Sound::FREQUENCY;
/* FIXME: use global music volume to scale the output here */
int n = duh_render(renderer, 16, 0, volume, delta, samples, data);
}
void DumbPlayer::setVolume(double volume){
this->volume = volume;
}
DumbPlayer::~DumbPlayer(){
duh_end_sigrenderer(renderer);
unload_duh(music_file);
}
DUH * DumbPlayer::loadDumbFile(const char * path){
DUH * what;
for (int i = 0; i < 4; i++){
/* the order of trying xm/s3m/it/mod matters because mod could be
* confused with one of the other formats, so load it last.
*/
switch (i){
case 0 : {
what = dumb_load_xm_quick(path);
break;
}
case 1 : {
what = dumb_load_s3m_quick(path);
break;
}
case 2 : {
what = dumb_load_it_quick(path);
break;
}
case 3 : {
what = dumb_load_mod_quick(path);
break;
}
}
if (what != NULL){
Global::debug(0) << "Loaded " << path << " type " << typeToExtension(i) << "(" << i << ")" << std::endl;
return what;
}
}
return NULL;
}
GMEPlayer::GMEPlayer(const char * path):
emulator(NULL){
gme_err_t fail = gme_open_file(path, &emulator, Sound::FREQUENCY);
if (fail != NULL){
Global::debug(0) << "GME load error for " << path << ": " << fail << std::endl;
throw MusicException(__FILE__, __LINE__, "Could not load GME file");
}
emulator->start_track(0);
Global::debug(0) << "Loaded GME file " << path << std::endl;
}
void GMEPlayer::render(void * stream, int length){
/* length/2 to convert bytes to short */
emulator->play(length * 2, (short*) stream);
if (emulator->track_ended()){
gme_info_t * info;
gme_track_info(emulator, &info, 0);
int intro = info->intro_length;
emulator->start_track(0);
// Global::debug(0) << "Seeking " << intro << "ms. Track length " << info->length << "ms" << std::endl;
/* skip past the intro if there is a loop */
if (info->loop_length != 0){
emulator->seek(intro);
}
}
/* scale for volume */
for (int i = 0; i < length * 2; i++){
short & sample = ((short *) stream)[i];
sample *= volume;
}
/*
short large = 0;
short small = 0;
for (int i = 0; i < length / 2; i++){
// ((short *) stream)[i] *= 2;
short z = ((short *) stream)[i];
if (z < small){
small = z;
}
if (z > large){
large = z;
}
}
Global::debug(0) << "Largest " << large << " Smallest " << small << std::endl;
*/
}
void GMEPlayer::setVolume(double volume){
this->volume = volume;
}
GMEPlayer::~GMEPlayer(){
delete emulator;
}
#ifdef HAVE_MP3_MPG123
/* initialize the mpg123 library and open up an mp3 file for reading */
static void initializeMpg123(mpg123_handle ** mp3, const char * path){
/* Initialize */
if (mpg123_init() != MPG123_OK){
throw MusicException(__FILE__, __LINE__, "Could not initialize mpg123");
}
try{
*mp3 = mpg123_new(NULL, NULL);
if (*mp3 == NULL){
throw MusicException(__FILE__,__LINE__, "Could not allocate mpg handle");
}
mpg123_format_none(*mp3);
/* allegro wants unsigned samples but mpg123 can't actually provide unsigned
* samples even though it has an enum for it, MPG123_ENC_UNSIGNED_16. this
* was rectified in 1.13.0 or something, but for now signed samples are ok.
*/
int error = mpg123_format(*mp3, Sound::FREQUENCY, MPG123_STEREO, MPG123_ENC_SIGNED_16);
if (error != MPG123_OK){
Global::debug(0) << "Could not set format for mpg123 handle" << std::endl;
}
/* FIXME workaround for libmpg issues with "generic" decoder frequency not being set */
error = mpg123_open(*mp3, (char*) path);
if (error == -1){
std::ostringstream error;
error << "Could not open mpg123 file " << path << " error code " << error;
throw MusicException(__FILE__,__LINE__, error.str());
}
/* reading a frame is the only surefire way to get mpg123 to set the
* sampling_frequency which it needs to set the decoder a few lines below
*/
size_t dont_care;
unsigned char tempBuffer[4096];
error = mpg123_read(*mp3, tempBuffer, sizeof(tempBuffer), &dont_care);
if (!(error == MPG123_OK || error == MPG123_NEW_FORMAT)){
std::ostringstream error;
error << "Could not read mpg123 file " << path << " error code " << error;
throw MusicException(__FILE__,__LINE__, error.str());
}
mpg123_close(*mp3);
/* stream has progressed a little bit so reset it by opening it again */
error = mpg123_open(*mp3, (char*) path);
if (error == -1){
std::ostringstream error;
error << "Could not open mpg123 file " << path << " error code " << error;
throw MusicException(__FILE__,__LINE__, error.str());
}
/* FIXME end */
/* some of the native decoders aren't stable in older versions of mpg123
* so just use generic for now. 1.13.1 should work better
*/
error = mpg123_decoder(*mp3, "generic");
if (error != MPG123_OK){
std::ostringstream error;
error << "Could not use 'generic' mpg123 decoder for " << path << " error code " << error;
throw MusicException(__FILE__,__LINE__, error.str());
}
// Global::debug(0) << "mpg support " << mpg123_format_support(mp3, Sound::FREQUENCY, MPG123_ENC_SIGNED_16) << std::endl;
/*
double base, really, rva;
mpg123_getvolume(*mp3, &base, &really, &rva);
// Global::debug(0) << "mpg volume base " << base << " really " << really << " rva " << rva << std::endl;
base_volume = base;
long rate;
int channels, encoding;
mpg123_getformat(*mp3, &rate, &channels, &encoding);
// Global::debug(0) << path << " rate " << rate << " channels " << channels << " encoding " << encoding << std::endl;
*/
} catch (const MusicException & fail){
if (*mp3 != NULL){
mpg123_close(*mp3);
mpg123_delete(*mp3);
*mp3 = NULL;
}
mpg123_exit();
throw;
}
}
static const int MPG123_BUFFER_SIZE = 1 << 11;
Mp3Player::Mp3Player(const char * path):
mp3(NULL){
initializeMpg123(&mp3, path);
long rate = 0;
int channels = 0, encoding = 0;
mpg123_getformat(mp3, &rate, &channels, &encoding);
}
void Mp3Player::render(void * data, int samples){
/* buffer * 4 for 16 bits per sample * 2 samples for stereo */
size_t out = 0;
mpg123_read(mp3, (unsigned char *) data, samples * 4, &out);
/*
long rate;
int channels, encoding;
mpg123_getformat(mp3, &rate, &channels, &encoding);
Global::debug(0) << "rate " << rate << " channels " << channels << " encoding " << encoding << std::endl;
*/
}
void Mp3Player::setVolume(double volume){
mpg123_volume(mp3, volume);
/*
this->volume = volume;
// mpg123_volume(mp3, volume * base_volume / 5000);
mpg123_volume(mp3, 0.0001);
*/
// mpg123_volume(mp3, volume);
}
Mp3Player::~Mp3Player(){
mpg123_close(mp3);
mpg123_exit();
}
#endif /* MP3_MPG123 */
+#ifdef HAVE_OGG
+OggPlayer::OggPlayer(const char * path){
+}
+
+void OggPlayer::render(void * data, int length){
+}
+
+void OggPlayer::setVolume(double volume){
+ this->volume = volume;
+ // Mix_VolumeMusic(volume * MIX_MAX_VOLUME);
+}
+
+OggPlayer::~OggPlayer(){
+}
+#endif /* OGG */
+
+#ifdef HAVE_MP3_MAD
+ /* TODO */
+Mp3Player::Mp3Player(const char * path):
+stream(NULL){
+ /* TODO */
+}
+
+void Mp3Player::setVolume(double volume){
+ /* TODO */
+}
+
+Mp3Player::~Mp3Player(){
+ /* TODO */
+}
+#endif /* MP3_MAD */
+
+
}
diff --git a/util/music-player.h b/util/music-player.h
index 4fdf4dfb..224ac093 100644
--- a/util/music-player.h
+++ b/util/music-player.h
@@ -1,154 +1,149 @@
#ifndef _paintown_music_player_h
#define _paintown_music_player_h
#ifdef USE_SDL
/* for Uint8 */
#include <SDL.h>
#include "sdl/mixer/SDL_mixer.h"
#endif
#ifdef HAVE_MP3_MPG123
#include <mpg123.h>
#endif
#ifdef HAVE_MP3_MAD
#include <mad.h>
#endif
#include "pointer.h"
struct DUH;
struct DUH_SIGRENDERER;
#ifdef USE_ALLEGRO
struct AL_DUH_PLAYER;
struct AUDIOSTREAM;
struct LOGG_Stream;
#endif
class Music_Emu;
#ifdef USE_ALLEGRO5
struct ALLEGRO_AUDIO_STREAM;
struct ALLEGRO_EVENT_QUEUE;
#endif
namespace Util{
class MusicPlayer;
/* implemented by some backend: allegro4/sdl/allergo5 */
class MusicRenderer{
public:
MusicRenderer();
virtual ~MusicRenderer();
void poll(MusicPlayer & player);
void play(MusicPlayer & player);
void pause();
protected:
#ifdef USE_SDL
static void mixer(void * arg, Uint8 * stream, int length);
#endif
#ifdef USE_ALLEGRO
AUDIOSTREAM * stream;
#endif
#ifdef USE_ALLEGRO5
ALLEGRO_AUDIO_STREAM * stream;
ALLEGRO_EVENT_QUEUE * queue;
#endif
};
class MusicPlayer{
public:
MusicPlayer();
virtual void play();
virtual void poll();
virtual void pause();
virtual void setVolume(double volume) = 0;
virtual ~MusicPlayer();
/* length is in samples not bytes */
virtual void render(void * stream, int length) = 0;
virtual inline double getVolume() const {
return volume;
}
protected:
double volume;
ReferenceCount<MusicRenderer> out;
};
/* uses the GME library, plays nintendo music files and others */
class GMEPlayer: public MusicPlayer {
public:
GMEPlayer(const char * path);
virtual void setVolume(double volume);
virtual ~GMEPlayer();
virtual void render(void * stream, int length);
protected:
Music_Emu * emulator;
};
#ifdef HAVE_OGG
/* Maybe have some common sdl mixer class that this can inherit? */
class OggPlayer: public MusicPlayer {
public:
OggPlayer(const char * path);
- virtual void play();
-
- virtual void poll();
- virtual void pause();
virtual void setVolume(double volume);
virtual void render(void * stream, int length);
virtual ~OggPlayer();
protected:
-#if USE_SDL
- Mix_Music * music;
-#endif
+ /*
#ifdef USE_ALLEGRO
struct LOGG_Stream * stream;
#endif
+*/
};
#endif
#if defined (HAVE_MP3_MPG123) || defined (HAVE_MP3_MAD)
/* Interface for mp3s */
class Mp3Player: public MusicPlayer {
public:
Mp3Player(const char * path);
virtual void setVolume(double volume);
virtual void render(void * data, int length);
virtual ~Mp3Player();
protected:
#ifdef HAVE_MP3_MPG123
mpg123_handle * mp3;
double base_volume;
#elif HAVE_MP3_MAD
#endif
};
#endif
/* interface to DUMB, plays mod/s3m/xm/it */
class DumbPlayer: public MusicPlayer {
public:
DumbPlayer(const char * path);
virtual void setVolume(double volume);
virtual void render(void * data, int samples);
virtual ~DumbPlayer();
protected:
DUH * loadDumbFile(const char * path);
protected:
DUH * music_file;
DUH_SIGRENDERER * renderer;
};
}
#endif
diff --git a/util/ogg/logg.c b/util/ogg/logg.c
index 47b9deee..367f8e3f 100644
--- a/util/ogg/logg.c
+++ b/util/ogg/logg.c
@@ -1,269 +1,259 @@
#if defined(HAVE_OGG) && defined(USE_ALLEGRO)
#include <string.h>
#include <allegro.h>
#include <allegro/internal/aintern.h>
#include "logg.h"
/* XXX requires testing */
#ifdef ALLEGRO_BIG_ENDIAN
const int ENDIANNESS = 1;
#endif
#ifdef ALLEGRO_LITTLE_ENDIAN
const int ENDIANNESS = 0;
#endif
static int logg_bufsize = 1024*64;
-SAMPLE* logg_load(const char* filename)
-{
- OggVorbis_File ovf;
- FILE* file;
- vorbis_info* vi;
- SAMPLE* samp;
- int numRead;
- int offset = 0;
- int bitstream;
- char *buf = malloc(logg_bufsize);
-
- file = fopen(filename, "rb");
- if (!file) {
- uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", filename);
- free(buf);
- return 0;
- }
-
- if (ov_open_callbacks(file, &ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) {
- strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE);
- fclose(file);
- free(buf);
- return 0;
- }
-
- vi = ov_info(&ovf, -1);
-
- samp = (SAMPLE*)_al_malloc(sizeof(SAMPLE));
- if (!samp) {
- ov_clear(&ovf);
- free(buf);
- return 0;
- }
-
- samp->bits = 16;
- samp->stereo = vi->channels > 1 ? 1 : 0;
- samp->freq = vi->rate;
- samp->priority = 128;
- samp->len = ov_pcm_total(&ovf, -1);
- samp->loop_start = 0;
- samp->loop_end = samp->len;
- samp->data = _al_malloc(sizeof(unsigned short) * samp->len * 2);
-
- while ((numRead = ov_read(&ovf, buf, logg_bufsize,
- ENDIANNESS, 2, 0, &bitstream)) != 0) {
- memcpy((unsigned char*)samp->data+offset, buf, numRead);
- offset += numRead;
- }
-
- ov_clear(&ovf);
- free(buf);
-
- return samp;
+SAMPLE* logg_load(const char* filename){
+ OggVorbis_File ovf;
+ FILE* file;
+ vorbis_info* vi;
+ SAMPLE* samp;
+ int numRead;
+ int offset = 0;
+ int bitstream;
+ char *buf = malloc(logg_bufsize);
+
+ file = fopen(filename, "rb");
+ if (!file) {
+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", filename);
+ free(buf);
+ return 0;
+ }
+
+ if (ov_open_callbacks(file, &ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) {
+ strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE);
+ fclose(file);
+ free(buf);
+ return 0;
+ }
+
+ vi = ov_info(&ovf, -1);
+
+ samp = (SAMPLE*)_al_malloc(sizeof(SAMPLE));
+ if (!samp) {
+ ov_clear(&ovf);
+ free(buf);
+ return 0;
+ }
+
+ samp->bits = 16;
+ samp->stereo = vi->channels > 1 ? 1 : 0;
+ samp->freq = vi->rate;
+ samp->priority = 128;
+ samp->len = ov_pcm_total(&ovf, -1);
+ samp->loop_start = 0;
+ samp->loop_end = samp->len;
+ samp->data = _al_malloc(sizeof(unsigned short) * samp->len * 2);
+
+ while ((numRead = ov_read(&ovf, buf, logg_bufsize,
+ ENDIANNESS, 2, 0, &bitstream)) != 0) {
+ memcpy((unsigned char*)samp->data+offset, buf, numRead);
+ offset += numRead;
+ }
+
+ ov_clear(&ovf);
+ free(buf);
+
+ return samp;
}
-int logg_get_buffer_size(void)
-{
- return logg_bufsize;
+int logg_get_buffer_size(void){
+ return logg_bufsize;
}
-void logg_set_buffer_size(int size)
-{
- ASSERT(size > 0);
- logg_bufsize = size;
+void logg_set_buffer_size(int size){
+ ASSERT(size > 0);
+ logg_bufsize = size;
}
-static int logg_open_file_for_streaming(struct LOGG_Stream* s)
-{
- FILE* file;
- vorbis_info* vi;
+static int logg_open_file_for_streaming(struct LOGG_Stream* s){
+ FILE* file;
+ vorbis_info* vi;
- file = fopen(s->filename, "rb");
- if (!file) {
- uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", s->filename);
- return 1;
- }
+ file = fopen(s->filename, "rb");
+ if (!file) {
+ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", s->filename);
+ return 1;
+ }
- if (ov_open_callbacks(file, &s->ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) {
- strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE);
- fclose(file);
- return 1;
- }
+ if (ov_open_callbacks(file, &s->ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) {
+ strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE);
+ fclose(file);
+ return 1;
+ }
- vi = ov_info(&s->ovf, -1);
+ vi = ov_info(&s->ovf, -1);
- s->bits = 16;
- s->stereo = vi->channels > 1 ? 1 : 0;
- s->freq = vi->rate;
- s->len = ov_pcm_total(&s->ovf, -1);
+ s->bits = 16;
+ s->stereo = vi->channels > 1 ? 1 : 0;
+ s->freq = vi->rate;
+ s->len = ov_pcm_total(&s->ovf, -1);
- return 0;
+ return 0;
}
-static int read_ogg_data(struct LOGG_Stream* s)
-{
- int read = 0;
- int bitstream;
-
- int page = s->current_page;
- s->current_page++;
- s->current_page %= OGG_PAGES_TO_BUFFER;
-
- memset(s->buf[page], 0, logg_bufsize);
-
- while (read < logg_bufsize) {
- int thisRead = ov_read(&s->ovf, s->buf[page]+read,
- logg_bufsize-read,
- ENDIANNESS, 2, 0, &bitstream);
- if (thisRead == 0) {
- if (s->loop) {
- ov_clear(&s->ovf);
- if (logg_open_file_for_streaming(s)) {
- return -1;
- }
- }
- else {
- return read;
- }
- }
- read += thisRead;
- }
-
- return read;
+static int read_ogg_data(struct LOGG_Stream* s){
+ int read = 0;
+ int bitstream;
+
+ int page = s->current_page;
+ s->current_page++;
+ s->current_page %= OGG_PAGES_TO_BUFFER;
+
+ memset(s->buf[page], 0, logg_bufsize);
+
+ while (read < logg_bufsize) {
+ int thisRead = ov_read(&s->ovf, s->buf[page]+read,
+ logg_bufsize-read,
+ ENDIANNESS, 2, 0, &bitstream);
+ if (thisRead == 0) {
+ if (s->loop) {
+ ov_clear(&s->ovf);
+ if (logg_open_file_for_streaming(s)) {
+ return -1;
+ }
+ }
+ else {
+ return read;
+ }
+ }
+ read += thisRead;
+ }
+
+ return read;
}
-static int logg_play_stream(struct LOGG_Stream* s)
-{
- int len;
- int i;
-
- s->current_page = 0;
- s->playing_page = -1;
-
- len = logg_bufsize / (s->stereo ? 2 : 1)
- / (s->bits / (sizeof(char)*8));
-
- s->audio_stream = play_audio_stream(len,
- s->bits, s->stereo,
- s->freq, s->volume, s->pan);
-
- if (!s->audio_stream) {
- return 1;
- }
-
- for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
- s->buf[i] = malloc(logg_bufsize);
- if (!s->buf[i]) {
- logg_destroy_stream(s);
- return 1;
- }
- if (read_ogg_data(s) < 0) {
- return 1;
- }
- }
-
- return 0;
+static int logg_play_stream(struct LOGG_Stream* s){
+ int len;
+ int i;
+
+ s->current_page = 0;
+ s->playing_page = -1;
+
+ len = logg_bufsize / (s->stereo ? 2 : 1)
+ / (s->bits / (sizeof(char)*8));
+
+ s->audio_stream = play_audio_stream(len,
+ s->bits, s->stereo,
+ s->freq, s->volume, s->pan);
+
+ if (!s->audio_stream) {
+ return 1;
+ }
+
+ for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
+ s->buf[i] = malloc(logg_bufsize);
+ if (!s->buf[i]) {
+ logg_destroy_stream(s);
+ return 1;
+ }
+ if (read_ogg_data(s) < 0) {
+ return 1;
+ }
+ }
+
+ return 0;
}
-struct LOGG_Stream* logg_get_stream(const char* filename, int volume, int pan, int loop)
-{
- struct LOGG_Stream* s = calloc(1, sizeof(struct LOGG_Stream));
- if (!s) {
- return 0;
- }
+struct LOGG_Stream* logg_get_stream(const char* filename, int volume, int pan, int loop){
+ struct LOGG_Stream* s = calloc(1, sizeof(struct LOGG_Stream));
+ if (!s) {
+ return 0;
+ }
- s->filename = strdup(filename);
+ s->filename = strdup(filename);
- if (!s->filename) {
- free(s);
- return 0;
- }
+ if (!s->filename) {
+ free(s);
+ return 0;
+ }
- if (logg_open_file_for_streaming(s)) {
- logg_destroy_stream(s);
- return 0;
- }
+ if (logg_open_file_for_streaming(s)) {
+ logg_destroy_stream(s);
+ return 0;
+ }
- s->volume = volume;
- s->pan = pan;
- s->loop = loop;
+ s->volume = volume;
+ s->pan = pan;
+ s->loop = loop;
- if (logg_play_stream(s)) {
- logg_destroy_stream(s);
- return 0;
- }
+ if (logg_play_stream(s)) {
+ logg_destroy_stream(s);
+ return 0;
+ }
- return s;
+ return s;
}
-int logg_update_stream(struct LOGG_Stream* s)
-{
- unsigned char* data = get_audio_stream_buffer(s->audio_stream);
-
- if (!data) {
- if (s->current_page != s->playing_page) {
- int read = read_ogg_data(s);
- if (read < logg_bufsize) {
- return 0;
- }
- else {
- return 1;
- }
- }
- else {
- return 1;
- }
- }
-
- s->playing_page++;
- s->playing_page %= OGG_PAGES_TO_BUFFER;
- memcpy(data, s->buf[s->playing_page], logg_bufsize);
-
- free_audio_stream_buffer(s->audio_stream);
-
- return 1;
+int logg_update_stream(struct LOGG_Stream* s){
+ unsigned char* data = get_audio_stream_buffer(s->audio_stream);
+
+ if (!data) {
+ if (s->current_page != s->playing_page) {
+ int read = read_ogg_data(s);
+ if (read < logg_bufsize) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+ }
+ else {
+ return 1;
+ }
+ }
+
+ s->playing_page++;
+ s->playing_page %= OGG_PAGES_TO_BUFFER;
+ memcpy(data, s->buf[s->playing_page], logg_bufsize);
+
+ free_audio_stream_buffer(s->audio_stream);
+
+ return 1;
}
-void logg_stop_stream(struct LOGG_Stream* s)
-{
- int i;
+void logg_stop_stream(struct LOGG_Stream* s){
+ int i;
- stop_audio_stream(s->audio_stream);
- for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
- free(s->buf[i]);
- s->buf[i] = 0;
- }
+ stop_audio_stream(s->audio_stream);
+ for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
+ free(s->buf[i]);
+ s->buf[i] = 0;
+ }
}
-int logg_restart_stream(struct LOGG_Stream* s)
-{
- return logg_play_stream(s);
+int logg_restart_stream(struct LOGG_Stream* s){
+ return logg_play_stream(s);
}
-void logg_destroy_stream(struct LOGG_Stream* s)
-{
- int i;
-
- if (s->audio_stream) {
- stop_audio_stream(s->audio_stream);
- }
- ov_clear(&s->ovf);
- for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
- if (s->buf[i]) {
- free(s->buf[i]);
- }
- }
- free(s->filename);
- free(s);
+void logg_destroy_stream(struct LOGG_Stream* s){
+ int i;
+
+ if (s->audio_stream) {
+ stop_audio_stream(s->audio_stream);
+ }
+
+ ov_clear(&s->ovf);
+ for (i = 0; i < OGG_PAGES_TO_BUFFER; i++) {
+ if (s->buf[i]) {
+ free(s->buf[i]);
+ }
+ }
+ free(s->filename);
+ free(s);
}
#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 10:37 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68466
Default Alt Text
(30 KB)

Event Timeline