Why too fast song tact by LibMad on RH9 Linux?

"Maxipoint Rep Office" <[email protected]> Tue, 17 Aug 2004 11:27:03 +0200
Newsgroups gmane.comp.audio.mad.user
Message-ID <[email protected]>
Do you have a soundcard that will only play at 48KHz?
RE: no, because same mp3s on windows play OK

  Or perhaps it's a MP3
recorded at 22KHz and you've opened the sound device at 44KHz.
RE: no you can see in code that I am setRate (44100);

all songs are recorded on the 192kbps 44.1kHz. Maybe I must define kbps too?

-GP


#include <sys/soundcard.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>

#include "audio.h"

#include <qstring.h>




CAudioSink::CAudioSink ()
{
    // initialize device
    if ((sound_dev = open ("/dev/sound/dsp", O_WRONLY)) == -1)
        sound_dev = open ("/dev/dsp", O_WRONLY);

    if (sound_dev == -1)
        throw tr ("Failed to initialize OSS device");

    if (ioctl (sound_dev, SNDCTL_DSP_SYNC, 0) == -1)
        throw tr ("Failed to sync with DSP");

    // TODO: this must be moved to another method to handle mono data
    channels = 2;
    ioctl (sound_dev, SNDCTL_DSP_CHANNELS, &channels);
    ioctl (sound_dev, SNDCTL_DSP_SYNC, 0);

    int fmt = AFMT_S16_LE;

    // set 16-bit data in little-endian format
    ioctl (sound_dev, SNDCTL_DSP_SAMPLESIZE, &fmt);
    ioctl (sound_dev, SNDCTL_DSP_SYNC, 0);

    // set default playback rate
    setRate (44100);
}



CAudioSink::~CAudioSink ()
{
    close (sound_dev);
}


// set samplerate of data
void CAudioSink::setRate (int _rate)
{
    rate = _rate;

    ioctl (sound_dev, SNDCTL_DSP_SPEED, &rate);
}


// reset audio device
void CAudioSink::flush ()
{
    ioctl (sound_dev, SNDCTL_DSP_RESET, 0);
}



// play data buffer
void CAudioSink::play (unsigned char* ptr, int len)
{
    while (len)
    {
        int wrote;

        wrote = write (sound_dev, ptr, len);

        // this check handles that fact that write syscall can be
        // interrupted at any time
        if (wrote == -1)
        {
            if (errno == EINTR)
                continue;
            else
                break;
        }

        ptr += wrote;
        len -= wrote;
    }
}