Sound apis

Member
Posts: 105
Joined: 2007.03
Post: #1
I'm looking for the simplest possible way to play sounds and music. I assume that sound manager is or will be soon(if I'm wrong please correct me) and core audio looks awfully complicated. Could someone please tell me what the all around simplest audio api is?
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #2
SDL_mixer is the easiest that I've used, though the API isn't the best and documentation is non-existant practically. It supports loading a decent number of formats and handles streamed music for you.

I've also found OpenAL + Ogg/Vorbis to be pretty easy. Ogg/Vorbis has an excellent API IMO as it's pretty easy to use and well documented. If you want streamed and looping music to work it's not too difficult.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
I'll second OpenAL + Ogg/Vorbis as not being too bad. I can provide the sound code from Outnumbered (both sample-accurate looping music and 3D localized sounds) if it's wanted.

I've also been using CoreAudio a little in the last week or so and it's not nearly as bad as it looked at first sight (though still substantially worse than it need be IMO Wink )
Quote this message in a reply
Member
Posts: 715
Joined: 2003.04
Post: #4
Ok I'll third the recomendations so far, especially since I recommended it to another project twenty four hours earlier.
Quote this message in a reply
Moderator
Posts: 682
Joined: 2002.11
Post: #5
I'd like to see OSC's code, if he wants to upload it.

My web site - Games, music, Python stuff
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #6
This is some old code I made for one of the CreateMacGames.org Coding Challenges (site is gone):

SoundFX3D.h
Code:
/*
*  SoundFX3D.h
*  SDLBlindF
*
*  Created by Ignacio on Mon Jul 12 2004.
*  Copyright (c) 2004 Juan Ignacio Garcia. All rights reserved.
*
*/

#ifndef __SOUND_FX_3D_H__
#define __SOUND_FX_3D_H__

#include "CVector3.h"
#include "GlobalTime.h"
#include <OpenAL/al.h>
#include <OpenAL/alut.h>
#include <OpenAL/alctypes.h>

class SoundFX3D
{
public:
    SoundFX3D(const char *fileName)                    { _ready = false; Load(fileName);    _volume = 1.0f; _pitch = 1.0f; };    // Constructor
    SoundFX3D(ALuint indexBuffer)                    { _ready = false; Load(indexBuffer); _volume = 1.0f; _pitch = 1.0f;};    // Constructor
    ~SoundFX3D();
    
    void   Load(const char *fileName);
    void   Load(ALuint indexBuffer);
    void   Play()                                        { alSourcePlay(_indexSource); };
    void   Pause()                                        { alSourcePause(_indexSource); };
    void   Stop()                                        { alSourceStop(_indexSource); alSourceRewind(_indexSource); };
    void   Rewind()                                        { alSourceRewind(_indexSource); };
    bool   isPlaying()                                    { ALint state; alGetSourcei(_indexSource,AL_SOURCE_STATE,&state); return (state == AL_PLAYING); };
    void   SetLoop(bool loop)                            { alSourcei(_indexSource,AL_LOOPING,loop); };
    void   MoveTo(const CVector3& vPos)                    { if (_time) { SetVel(((_vPos-vPos           )*10000)/_time->deltaTime); } SetPos(vPos);  };
    void   MoveTo(ALfloat x, ALfloat y, ALfloat z)        { if (_time) { SetVel(((_vPos-CVector3(x,y,z))*10000)/_time->deltaTime); } SetPos(x,y,z); };
    void   MoveAndAimTo(const CVector3& vPos)            { if (_time) { SetDir(_vPos-vPos           ); SetVel((_vDir*10000)/_time->deltaTime); } SetPos(vPos);  };
    void   MoveAndAimTo(ALfloat x, ALfloat y, ALfloat z){ if (_time) { SetDir(_vPos-CVector3(x,y,z)); SetVel((_vDir*10000)/_time->deltaTime); } SetPos(x,y,z); };
    void   SetPos(const CVector3& vPos)                    { alSourcefv(_indexSource, AL_POSITION, (ALfloat*)&vPos); _vPos = vPos; };
    void   SetPos(ALfloat x, ALfloat y, ALfloat z)        { alSource3f(_indexSource, AL_POSITION,x,y,z); _vPos = CVector3(x,y,z); };
    void   SetDir(const CVector3& vDir)                    { alSourcefv(_indexSource, AL_DIRECTION,(ALfloat*)&vDir); _vDir = vDir; };
    void   SetDir(ALfloat x, ALfloat y, ALfloat z)        { alSource3f(_indexSource, AL_DIRECTION,x,y,z); _vDir = CVector3(x,y,z); };
    void   SetVel(const CVector3& vVel)                    { alSourcefv(_indexSource, AL_VELOCITY, (ALfloat*)&vVel); _vVel = vVel; };
    void   SetVel(ALfloat x, ALfloat y, ALfloat z)        { alSource3f(_indexSource, AL_VELOCITY,x,y,z); _vVel = CVector3(x,y,z); };
    CVector3 GetPos() const                                { return _vPos; };
    CVector3 GetDir() const                                { return _vDir; };
    CVector3 GetVel() const                                { return _vVel; };
    void   SetVolume(float volume)                        { alSourcef(_indexSource,AL_GAIN,volume); _volume = volume; };
    float  GetVolume()                                    { return _volume; };
    void   SetPitch(float pitch)                        { alSourcef(_indexSource,AL_PITCH,pitch); _pitch = pitch; };
    float  GetPitch()                                    { return _pitch; };
    void   Reset()                                        { Stop(); SetLoop(false); SetPos(CVector3()); SetDir(CVector3()); SetVel(CVector3()); SetVolume(1.0f); SetPitch(1.0f); };
    ALuint GetIndexBuffer()                                { return _indexBuffer; };
    ALuint GetIndexSource()                                { return _indexSource; };
    
    // Only one global listener - the same for all sound sources
    static void SetListenerPos(const CVector3& vPos)            { alListenerfv(AL_POSITION, (ALfloat*)&vPos); _vListenerPos = vPos; };
    static void SetListenerPos(ALfloat x, ALfloat y, ALfloat z) { alListener3f(AL_POSITION,x,y,z); _vListenerPos = CVector3(x,y,z); };
    static void SetListenerVel(const CVector3& vVel)            { alListenerfv(AL_VELOCITY, (ALfloat*)&vVel); _vListenerVel = vVel; };
    static void SetListenerVel(ALfloat x, ALfloat y, ALfloat z)    { alListener3f(AL_VELOCITY,x,y,z); _vListenerVel = CVector3(x,y,z); };
    static void SetListenerAt(const CVector3& vAt)                { _vListenerOri[0] = vAt; alListenerfv(AL_ORIENTATION, (ALfloat*)_vListenerOri); };
    static void SetListenerAt(ALfloat x, ALfloat y, ALfloat z)    { alListener3f(AL_ORIENTATION,x,y,z); _vListenerOri[0] = CVector3(x,y,z); };
    static void SetListenerUp(const CVector3& vUp)                { _vListenerOri[1] = vUp; alListenerfv(AL_ORIENTATION, (ALfloat*)_vListenerOri); };
    static void SetListenerUp(ALfloat x, ALfloat y, ALfloat z)    { alListener3f(AL_ORIENTATION,x,y,z); _vListenerOri[1] = CVector3(x,y,z); };
    static CVector3 GetListenerPos()                            { return _vListenerPos; };
    static CVector3 GetListenerVel()                             { return _vListenerVel; };
    static CVector3 GetListenerAt()                             { return _vListenerOri[0]; };
    static CVector3 GetListenerUp()                             { return _vListenerOri[1]; };
    static void  SetListenerVolume(float volume)                { alListenerf(AL_GAIN,volume); _listenerVolume = volume; };
    static float GetListenerVolume()                            { return _listenerVolume; };
    static void  ResetListener()                                { SetListenerPos(0.0f,0.0f,0.0f); SetListenerVel(0.0f,0.0f,0.0f); SetListenerAt(0.0f,0.0f,-1.0f); SetListenerUp(0.0f,1.0f,0.0f); SetListenerVolume(1.0f); };
    static void  SetTimeObject(GlobalTime *time)                { _time = time; };
    static void  Init()                                            { alutInit(0, NULL); alGetError(); alSetInteger(ALC_SPATIAL_RENDERING_QUALITY,ALC_SPATIAL_RENDERING_QUALITY_HIGH); };
    static void  Shutdown()                                        { alutExit(); };
    
private:
    ALuint   _indexBuffer;
    ALuint   _indexSource;
    CVector3 _vPos;
    CVector3 _vDir;
    CVector3 _vVel;
    float    _volume;
    float    _pitch;
    char     _fileName[64];
    bool     _ready;
    
    // Only one global listener - the same for all sound sources
    static CVector3    _vListenerPos;
    static CVector3    _vListenerVel;
    static CVector3    _vListenerOri[2]; // Orientation: at & up
    static float       _listenerVolume;
    static GlobalTime *_time;
    
};

#endif

SoundFX3D.cpp
Code:
/*
*  SoundFX3D3D.cpp
*  SDLBlindF
*
*  Created by Ignacio on Mon Jul 12 2004.
*  Copyright (c) 2004 Juan Ignacio Garcia. All rights reserved.
*
*/

#include "SoundFX3D.h"

#include <stdio.h>
#include <string.h> // para strcpy

GlobalTime *SoundFX3D::_time(NULL);
CVector3    SoundFX3D::_vListenerPos(0.0f,0.0f,0.0f);
CVector3    SoundFX3D::_vListenerVel(0.0f,0.0f,0.0f);
CVector3    SoundFX3D::_vListenerOri[2] = { CVector3(0.0f,0.0f,-1.0f), CVector3(0.0f,1.0f,0.0f) };
float        SoundFX3D::_listenerVolume(1.0f);

SoundFX3D::~SoundFX3D()
{
    if (alIsBuffer(_indexBuffer))
        alDeleteBuffers(1, &_indexBuffer);
}

void SoundFX3D::Load(const char *fileName)
{
    ALvoid *data;
    ALenum  format;
    ALsizei size,freq;
    
    strcpy(_fileName,fileName);
    alutLoadWAVFile(_fileName, &format, &data, &size, &freq);
    if (_ready)
    {
        alDeleteBuffers(1, &_indexBuffer);
    }
    _indexBuffer = 0;
    alGenBuffers(1, &_indexBuffer);

    alBufferData(_indexBuffer,format,data,size,freq);
    alutUnloadWAV(format, data, size, freq);
    Load(_indexBuffer);
}

void SoundFX3D::Load(ALuint indexBuffer)
{
    if (!_ready)
    {    
        _indexSource = 0;
        alGenSources(1, &_indexSource);
    }
    alSourcei(_indexSource, AL_BUFFER, _indexBuffer);
    _ready = true;
}

May be buggy, didn't get a lot of testing Wink
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
music.c
Code:
#include <assert.h>
#include <stdlib.h>

#include <vorbis/vorbisfile.h>

#include "music.h"
#include "openal.h"
#include "options.h"
#include "sound.h"

static OggVorbis_File _ovfile;
static ALenum         _format;
static ALsizei        _frequency;

#define BUFFER_SIZE 65536
#define BUFFER_COUNT 4

static char _data[BUFFER_SIZE];
static ALuint _buffers[BUFFER_COUNT];

static ALuint _source = 0;

static int _open_music(void)
{
    FILE *file = fopen("Music/Noise.ogg", "rb");
    if (file == NULL)
    {
        return 0;
    }
    
    vorbis_info *info;
    
    ov_open(file, &_ovfile, NULL, 0);
    
    info = ov_info(&_ovfile, -1);
    unsigned channel_count = info->channels == 1 ? 1 : 2;
    _format = channel_count == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
    _frequency = info->rate;
    
    return 1;
}

static void _fill_buffer(ALuint buffer)
{
    char *cursor = _data;
    long read_bytes = 0;

    int bitstream;
    long count;
    while (read_bytes < BUFFER_SIZE && (count = ov_read(
        &_ovfile,
        cursor,
        BUFFER_SIZE - read_bytes,
//#if defined(__BIG_ENDIAN__)
        1,
//#else
//        0,
//#endif
        2,
        1,
        &bitstream)) >= 0)
    {
        if (count == 0)
        {
            ov_raw_seek(&_ovfile, 0);
        }
        else
        {
            cursor += count;
            read_bytes += count;
        }
    }
    
    alBufferData(buffer, _format, _data, BUFFER_SIZE, _frequency);
}

static void _initial_fill_buffers(void)
{
    alGenBuffers(BUFFER_COUNT, _buffers);
    
    unsigned i;
    for (i = 0; i < BUFFER_COUNT; ++i)
    {
        _fill_buffer(_buffers[i]);
    }
}

static void _initialize_music(void)
{
    if (!_open_music())
    {
        return;
    }
    _initial_fill_buffers();
    
    alGenSources(1, &_source);
    
    alSourceQueueBuffers(_source, BUFFER_COUNT, _buffers);
    alSourcef(_source, AL_GAIN, 0.05f);
}

static void _start_music(void)
{
    if (_source == 0)
    {
        _initialize_music();
    }
    
    alSourcePlay(_source);
}

static void _stop_music(void)
{
    if (_source == 0)
    {
        _initialize_music();
    }
    
    alSourceStop(_source);
}

void start_stop_music_by_option(void)
{
    if (music)
    {
        _start_music();
    }
    else
    {
        _stop_music();
    }
}

void update_music(void)
{
    if (!music)
    {
        return;
    }

    ALint processed_count;
    alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed_count);
    assert(processed_count <= BUFFER_COUNT);
    
    if (processed_count == BUFFER_COUNT)
    {
        _stop_music();
        _start_music();
    }
    else
    {
        ALint i;
        for (i = 0; i < processed_count; ++i)
        {
            ALuint buffer;
            alSourceUnqueueBuffers(_source, 1, &buffer);
            assert(alIsBuffer(buffer));
            
            _fill_buffer(buffer);
            alSourceQueueBuffers(_source, 1, &buffer);
        }
    }
}

sound.c
Code:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <vorbis/vorbisfile.h>

#include "buzzing.h"
#include "camera.h"
#include "files.h"
#include "options.h"
#include "random.h"
#include "sound.h"

#define MAX_SOUNDS 32

typedef struct Sound_Handle
{
    char   name[256];
    ALuint sound;
}
Sound_Handle;

static unsigned     _sound_handle_count = 0;
static Sound_Handle _sound_handles[MAX_SOUNDS];

static void _clean_all_sounds(void)
{
    unsigned i;
    for (i = 0; i < _sound_handle_count; ++i)
    {
        alDeleteBuffers(1, &(_sound_handles[i].sound));
        _sound_handles[i].sound = 0;
    }
}

static int _load_sound(const char *path, ALuint *sound)
{
    FILE *file = fopen(path, "rb");
    if (file == NULL)
    {
        return 0;
    }
    
    OggVorbis_File ovfile;
    vorbis_info *info;
    
    ov_open(file, &ovfile, NULL, 0);
    
    info = ov_info(&ovfile, -1);
    unsigned channel_count = info->channels == 1 ? 1 : 2;
    ALenum format = channel_count == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
    ALsizei frequency = info->rate;
    
    ogg_int64_t pcm_total = ov_pcm_total(&ovfile, -1);
    ALsizei buffer_size = pcm_total * channel_count * sizeof(ALshort);
    void *buffer = malloc(buffer_size);
    char *cursor = buffer;
    
    int bitstream;
    long count;
    while ((count = ov_read(
        &ovfile,
        cursor,
        4096,
//#if defined(__BIG_ENDIAN__)
        1,
//#else
//        0,
//#endif
        2,
        1,
        &bitstream)) > 0)
    {
        cursor += count;
    }
    
    if (count < 0)
    {
        free(buffer);
        return 0;
    }
    
    ov_clear(&ovfile);
    
    alGenBuffers(1, sound);
    assert(alIsBuffer(*sound));
    
    alBufferData(
        *sound,
        format,
        buffer,
        buffer_size,
        frequency);
    
    free(buffer);
    
    return 1;
}

static void _load_and_store_sound(
    const char *path,
    const char *base_name,
    const char *extension)
{
    ALuint *existing_sound = sound_named(base_name);
    
    if (existing_sound == NULL || *existing_sound == 0)
    {
        ALuint *sound_reference = existing_sound == NULL ?
            &(_sound_handles[_sound_handle_count].sound) :
            existing_sound;
        
        int ok = _load_sound(path, sound_reference);
        if (ok && existing_sound == NULL)
        {
            size_t base_length = strlen(base_name);
            strncpy(
                _sound_handles[_sound_handle_count].name,
                base_name,
                base_length);
            _sound_handles[_sound_handle_count].name[base_length] = 0;
            
            ++_sound_handle_count;
        }
    }
}

#define MAX_SOURCES 32

static unsigned _source_count = 0;
static ALuint _sources[MAX_SOURCES];
static ALuint _buzz_sources[BUZZING_INSECT_COUNT];
static int _sources_initialized;

static void _initialize_sources(void)
{
    alGenSources(MAX_SOURCES, _sources);
    alGenSources(BUZZING_INSECT_COUNT, _buzz_sources);
    _sources_initialized = 1;
}

void load_sounds(void)
{
    if (!_sources_initialized)
    {
        _initialize_sources();
    }

    _clean_all_sounds();
    for_each_file("Sounds", ".ogg", _load_and_store_sound);
    
    ALuint buzz_sound = *sound_named("buzz");
    unsigned i;
    for (i = 0; i < BUZZING_INSECT_COUNT; ++i)
    {
        alSourcei(_buzz_sources[i], AL_BUFFER, buzz_sound);
        alSourcef(_buzz_sources[i], AL_ROLLOFF_FACTOR, 0.5f);
        alSourcei(_buzz_sources[i], AL_LOOPING, AL_TRUE);
    }
}

ALuint *sound_named(const char *name)
{
    unsigned i;
    for (i = 0; i < _sound_handle_count; ++i)
    {
        if (strcmp(_sound_handles[i].name, name) == 0)
        {
            return &(_sound_handles[i].sound);
        }
    }
    
    return NULL;
}


#define PITCH_VARIANCE 0.15f

void play_sound_once_at(const char *name, vector_t position, float volume)
{
    //fprintf(stderr, "play_sound_once -- %s\n", name);

    if (!sound_effects)
    {
        return;
    }

    if (_source_count == MAX_SOURCES)
    {
        //fprintf(stderr, "had to preemptively free a source\n");
        --_source_count;
        ALuint source = _sources[0];
        _sources[0] = _sources[_source_count];
        _sources[_source_count] = source;
        alSourceStop(source);
    }

    ALuint *sound = sound_named(name);
    if (sound == NULL)
    {
        return;
    }
    //fprintf(stderr, "sound: %u\n", (unsigned)sound);
    
    ALuint source = _sources[_source_count++];
    assert(alIsSource(source));
    
    alSourcei(source, AL_BUFFER, *sound);
    alSourcef(source, AL_ROLLOFF_FACTOR, 0.5f);
    alSourcef(source, AL_PITCH,
        1.0f + PITCH_VARIANCE * (2.0f * random_fraction() - 1.0f));
    alSource3f(source, AL_POSITION, position.x, position.y, position.z);
    alSourcef(source, AL_GAIN, volume);
    alSourcePlay(source);
}

extern void update_sound(void)
{
    ALfloat listener_position[3];
    listener_position[0] = camera_position.x;
    listener_position[1] = camera_position.y;
    listener_position[2] = camera_position.z;
    alListenerfv(AL_POSITION, listener_position);
    
    vector_t front = vector_subtract(focus_position, camera_position);
    vector_t right = vector_cross_product(front, vector3(0.0f, 1.0f, 0.0f));
    vector_t up = vector_cross_product(right, front);
    
    ALfloat orientation[6];
    orientation[0] = front.x;
    orientation[1] = front.y;
    orientation[2] = front.z;
    orientation[3] = up.x;
    orientation[4] = up.y;
    orientation[5] = up.z;
    alListenerfv(AL_ORIENTATION, orientation);
    
    alListenerf(AL_GAIN, 16.0f);
    
    unsigned i;
    for (i = 0; i < _source_count; /*don't ++i*/)
    {
        ALuint source = _sources[i];
    
        ALint state;
        alGetSourcei(source, AL_SOURCE_STATE, &state);
        if (state != AL_PLAYING)
        {
            --_source_count;
            _sources[i] = _sources[_source_count];
            _sources[_source_count] = source;
        }
        else
        {
            ++i;
        }
    }
    
    for (i = 0; i < BUZZING_INSECT_COUNT; ++i)
    {
        if (buzzing_insects[i].valid && sound_effects)
        {
            alSource3f(_buzz_sources[i], AL_POSITION,
                buzzing_insects[i].position.x,
                buzzing_insects[i].position.y,
                buzzing_insects[i].position.z);
            ALint state;
            alGetSourcei(_buzz_sources[i], AL_SOURCE_STATE, &state);
            if (state != AL_PLAYING)
            {
                alSourcePlay(_buzz_sources[i]);
            }
        }
        else
        {
            alSourceStop(_buzz_sources[i]);
        }
    }
    
    reset_buzzing();
}
Quote this message in a reply
Member
Posts: 105
Joined: 2007.03
Post: #8
Thanks alot, that was very helpful.
Quote this message in a reply
Member
Posts: 104
Joined: 2007.01
Post: #9
OpenAL works very well on Mac, but the OpenAL implementation on Windows and Linux leaves much to be desired. I've had occasional problems where it doesn't work with certain audio devices, or the audio is garbled - it happened with enough customers to qualify as a problem, in my book. I ended up converting my Dirk Dashing game to use SDL_mixer instead.

If your game is Mac-only, OpenAL is a fine choice. But if your game is cross-platform, I recommend going with SDL_mixer instead (especially if you only need simple audio playback). Both APIs are easy to use, though I found SDL_mixer to be a bit easier (though not as feature-rich).

There's a good set of OpenAL tutorials here:
http://www.devmaster.net/articles.php?catID=6

There's a good set of SDL_mixer tutorials here:
http://gpwiki.org/index.php/SDL_mixer
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #10
GolfHacker Wrote:OpenAL works very well on Mac, but the OpenAL implementation on Windows and Linux leaves much to be desired. I've had occasional problems where it doesn't work with certain audio devices, or the audio is garbled [...] if your game is cross-platform, I recommend going with SDL_mixer instead

Here is my SDL_mixer code (pretty similar interface to the OpenAL code I posted earlier):

SoundFX.h
Code:
/*
*  SoundFX.h
*  Test SDL
*
*  Created by Ignacio on Fri Aug 01 2003.
*  Copyright (c) 2003 Juan Ignacio Garcia. All rights reserved.
*
*/

#ifndef __SOUND_FX_H__
#define __SOUND_FX_H__

#include <SDL/SDL.h>
#include <SDL_Mixer/SDL_mixer.h>

class SoundFX
{
public:
    SoundFX(const char *fileName); // Constructor
    SoundFX(const char *fileName, int channel); // Constructor
    ~SoundFX();
    
    void Load(const char *fileName, int channel);
    void Play();
    void Play(int channel);
    void PlayWithVolume(float volume); // 'volume' entre 0.0f y 1.0f
    void PlayWithVolume(float volume, int channel); // 'volume' entre 0.0f y 1.0f
    void SetVolume(float volume); // 'volume' entre 0.0f y 1.0f
    float GetVolume();
    
private:
    //static bool _assignedChannels[32];
    Mix_Chunk *_sound;
    int _channel;
    float _volume;
    char _fileName[64];

};

#endif

SoundFX.cpp
Code:
/*
*  SoundFX.cpp
*  Test SDL
*
*  Created by Ignacio on Fri Aug 01 2003.
*  Copyright (c) 2003 Juan Ignacio Garcia. All rights reserved.
*
*/

#include "SoundFX.h"
#include <stdio.h>
#include <stdlib.h> // para exit (VER!)
#include <string.h> // para strcpy

SoundFX::SoundFX(const char *fileName)
{
    _sound = NULL;
    Load(fileName,-1); // -1 = auto
}

SoundFX::SoundFX(const char *fileName, int channel)
{
    _sound = NULL;
    Load(fileName,channel);
}

void SoundFX::Load(const char *fileName, int channel)
{
    if (_sound) Mix_FreeChunk(_sound);
    _sound = Mix_LoadWAV(fileName);
    if (!_sound)
    {
        ///@todo Implementar una variable private bool _ok y un metodo inline bool Error() {return _ok;};
        Mix_CloseAudio();
        SDL_Quit();
        printf("No se puede abrir %s!\n",fileName);
        exit(1);
    }
    strcpy(_fileName,fileName);
    _volume = 1.0f;
    _channel = channel;
}

void SoundFX::Play()
{
    Mix_PlayChannel(_channel,_sound,0);
}

void SoundFX::Play(int channel)
{
    Mix_PlayChannel(channel,_sound,0);
}

void SoundFX::PlayWithVolume(float volume) // 'volume' entre 0.0f y 1.0f
{
    _volume = volume;
    Mix_VolumeChunk(_sound,int(volume * 128.0f));
    Mix_PlayChannel(_channel,_sound,0);
}

void SoundFX::PlayWithVolume(float volume, int channel) // 'volume' entre 0.0f y 1.0f
{
    _volume = volume;
    Mix_VolumeChunk(_sound,int(volume * 128.0f));
    Mix_PlayChannel(channel,_sound,0);
}

void SoundFX::SetVolume(float volume) // 'volume' entre 0.0f y 1.0f
{
    _volume = volume;
    Mix_VolumeChunk(_sound,int(volume * 128.0f));
}

float SoundFX::GetVolume()
{
    return _volume;
}

SoundFX::~SoundFX()
{
    if (_sound) Mix_FreeChunk(_sound);
    _sound = NULL;
}

Music.h
Code:
/*
*  Music.h
*  Test SDL
*
*  Created by Ignacio on Sun Aug 03 2003.
*  Copyright (c) 2003 Juan Ignacio Garcia. All rights reserved.
*
*/

#ifndef __MUSIC_H__
#define __MUSIC_H__

#include <SDL/SDL.h>
#include <SDL_Mixer/SDL_mixer.h>

class Music
{
public:
    Music(const char *fileName); // Constructor
    Music(const char *fileName, int loops); // Constructor
    ~Music();
    
    void Load(const char *fileName, int loops);
    void Play();
    void Pause();
    void Resume();
    void Rewind();
    void Stop();
    void FadeIn(int ms);
    void FadeOut(int ms);
    bool isPlaying();
    bool isPaused();
    void PlayWithVolume(float volume);
    void SetVolume(float volume);
    float GetVolume();
        
private:
    Mix_Music *_music;
    int _loops;
    float _volume;
    char _fileName[64];
};

#endif

Music.cpp
Code:
/*
*  Music.cpp
*  Test SDL
*
*  Created by Ignacio on Sun Aug 03 2003.
*  Copyright (c) 2003 Juan Ignacio Garcia. All rights reserved.
*
*/

#include "Music.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Music::Music(const char *fileName)
{
    _music = NULL;
    Load(fileName,-1); // -1 = repetir para siempre
}

Music::Music(const char *fileName, int loops)
{
    _music = NULL;
    Load(fileName,loops);
}

void Music::Load(const char *fileName, int loops)
{
    if (_music) Mix_FreeMusic(_music);
    _music = Mix_LoadMUS(fileName);
    if (!_music)
    {
        Mix_CloseAudio();
        SDL_Quit();
        printf("Error: No se puede abrir el archivo %s\n",fileName);
        exit(1);
    }
    strcpy(_fileName,fileName);
    _volume = 1.0f;
    _loops = loops;
}

void Music::Play()
{
    if (!Mix_PlayingMusic()) Mix_PlayMusic(_music,_loops);
}

void Music::Pause()
{
    if (Mix_PlayingMusic() && !Mix_PausedMusic()) Mix_PauseMusic();
}

void Music::Resume()
{
    if (Mix_PausedMusic()) Mix_ResumeMusic();
}

void Music::Rewind()
{
    Mix_RewindMusic();
}

void Music::Stop()
{
    Mix_HaltMusic();
}

void Music::FadeIn(int ms)
{
    if (!Mix_PlayingMusic()) Mix_FadeInMusic(_music,_loops,ms);
}

void Music::FadeOut(int ms)
{
    if (Mix_PlayingMusic()) Mix_FadeOutMusic(ms);
}

bool Music::isPlaying()
{
    return (bool)Mix_PlayingMusic();
}

bool Music::isPaused()
{
    return (bool)Mix_PausedMusic();
}

void Music::PlayWithVolume(float volume)
{
    SetVolume(volume);
    Mix_PlayMusic(_music,0);
}

void Music::SetVolume(float volume) // 'volume' entre 0.0f y 1.0f
{
    Mix_VolumeMusic(int(volume*128.0f));
    _volume = volume;
}

float Music::GetVolume()
{
    return _volume;
}

Music::~Music()
{
    if (_music) Mix_FreeMusic(_music);
    _music = NULL;
}
Quote this message in a reply
Member
Posts: 105
Joined: 2007.03
Post: #11
I include:
#include <SDL/SDL.h>
#include <SDL_Mixer/SDL_mixer.h>

And I keep getting these same errors for some reason.


/Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/SDL_Mixer.framework/Headers/SDL_mixer.h:28:23: error: SDL_types.h: No such file or directory

/Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/SDL_Mixer.framework/Headers/SDL_mixer.h:29:23: error: SDL_rwops.h: No such file or directory

/Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/SDL_Mixer.framework/Headers/SDL_mixer.h:30:23: error: SDL_audio.h: No such file or directory

/Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/SDL_Mixer.framework/Headers/SDL_mixer.h:31:24: error: SDL_endian.h: No such file or directory

/Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/SDL_Mixer.framework/Headers/SDL_mixer.h:32:25: error: SDL_version.h: No such file or directory

/Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/SDL_Mixer.framework/Headers/SDL_mixer.h:33:24: error: begin_code.h: No such file or directory

/Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks/SDL_Mixer.framework/Headers/SDL_mixer.h:581:24: error: close_code.h: No such file or directory
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #12
You need to add <path to SDL.framework>/Headers to your header search paths. Either that or edit SDL_mixer.h to #include <SDL/whatever> instead of just <whatever>. Personally, I prefer the latter, since it's essentially broken as-is.
Quote this message in a reply
Member
Posts: 715
Joined: 2003.04
Post: #13
GolfHacker, do you have any information on the sound cards being used when people had issues with OpenAL.

We had an issue this winter.
I just decided to go digging for info about the sound card in question and what I to find is that RealTek sound cards are garbage,
get bad reviews from users who switch to other gear and their sound drivers tend to crap out for no apparent reason.

Do you have any insight into this?
Quote this message in a reply
Member
Posts: 104
Joined: 2007.01
Post: #14
igame3d Wrote:GolfHacker, do you have any information on the sound cards being used when people had issues with OpenAL.

We had an issue this winter.
I just decided to go digging for info about the sound card in question and what I to find is that RealTek sound cards are garbage,
get bad reviews from users who switch to other gear and their sound drivers tend to crap out for no apparent reason.

Do you have any insight into this?

Sorry for the delay in responding. Been away on vacation, and working diligently on finishing up coding for my upcoming Fashion Cents Deluxe release.

No, I don't know specifically what sound cards were being used. I know one of them was a motherboard with an onboard audio chip and running Windows XP. Another was a SoundBlaster Live! running on Ubuntu 7.04. I didn't record the rest of the problematic setups - probably should have. Sorry.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  So Many APIs Nick 19 8,057 Jul 23, 2004 10:44 AM
Last Post: Nick