Пример #1
0
/**
 * Play sound repeatedly.
 * @param name sound name
 * @return the channel the sample is played on. On any errors, -1 is returned.
 */
int SDLSound::playSoundRepeatedly(const char* name)
{
    int channel = -1;
    Mix_Chunk *chunk = findChunk(name);
    if (chunk) {
        if ((channel = Mix_PlayChannel(-1, chunk, -1)) == -1) {
            Mix_AllocateChannels(8 + Mix_AllocateChannels(-1));
            if ((channel = Mix_PlayChannel(-1, chunk, -1)) == -1) {
                LOG (("Couldn't play sound '%s': %s", name, Mix_GetError()));
            }
        }
    }

    return channel;
}
Пример #2
0
bool CubeWorld::exists( const Point& pt ) const
{
    // sanity
    checkPointBounds( pt );

    // Does there exist a pointer to the requested cube?
    OctreeChunk * chunk = findChunk( pt );

    if ( chunk )
    {
        return chunk->exists( calcRelativeChunkPoint(pt) );
    }
    else
    {
        return false;
    }
}
Пример #3
0
CubeData CubeWorld::get( const Point& pt ) const
{
    checkPointBounds( pt );

    // Find the chunk that holds the cube, and query the chunk for
    // the associated cube data. If no such cube chunk exists, then
    // simply return a null cube
    OctreeChunk * chunk = findChunk( pt );

    if ( chunk == NULL )
    {
        return CubeData::CreateNullCube();
    }
    else
    {
        return chunk->get( calcRelativeChunkPoint( pt ) );
    }
}
Пример #4
0
/**
 * Play sound once.
 * @param name sound name
 */
void SDLSound::playSound(const char* name)
{
    SoundData *sdata = findChunk(name);
    if (sdata)
    {
        if ( sdata->last_played.isTimeOut() )
        {
            if (Mix_PlayChannel(-1, sdata->getData(), 0) == -1)
            {
                //LOG (("Couldn't play sound '%s': %s", name, Mix_GetError()));
            }
            sdata->last_played.reset();
        }
        else
        {
//            LOGGER.debug("Skipped sound '%s' due to timeout", name);
        }
        
    }
}
Пример #5
0
/**
 * Play sound once.
 * @param name sound name
 * @param distance mag2 distance
 */
void SDLSound::playAmbientSound(const char* name, long distance)
{
    SoundData *sdata = findChunk(name);
    if (sdata)
    {
        if ( sdata->last_played.isTimeOut() )
        {
            int oldVolume = Mix_VolumeChunk(sdata->getData(), getSoundVolume(distance));
            if (Mix_PlayChannel(-1, sdata->getData(), 0) == -1)
            {
                //LOG (("Couldn't play sound '%s': %s", name, Mix_GetError()));
            }
            Mix_VolumeChunk(sdata->getData(), oldVolume);
            sdata->last_played.reset();
        }
        else
        {
//            LOGGER.debug("Skipped ambient sound '%s' due to timeout", name);
        }
    }
}
Пример #6
0
FILE*			openWavFile(const char *filename,
				short *format, long *speed,
				int *samples, short *channels, short *width)
{
  FILE* file;
  int16_t blockAlign, bitsPerSample, data16;
  int32_t bytesPerSec, len, data32;
  char tag[5];

  // open file
  file = fopen(filename, "rb");
  if (!file)
    return NULL;

  // automatically close file when we return
  FileCloser closer(file);

  // check that it's a valid sound file
  tag[4] = 0;
  if (readHeader(file, tag, &len))
    return NULL;
  if (strcmp(tag, "RIFF") != 0) {
    fprintf(stderr, "File isn't a RIFF file\n");
    return NULL;
  }
  if ((fread(tag, 1, 4, file) != 4) || strcmp(tag, "WAVE") != 0) {
    fprintf(stderr, "File isn't a proper WAVE file\n");
    return NULL;
  }
  if (findChunk(file, "fmt ", &len)) {
    fprintf(stderr, "Couldn't find format in WAVE\n");
    return NULL;
  }
  if (len < 16) {
    fprintf(stderr, "Chunk size not large enough\n");
    return NULL;
  }
  if (readShort(file, &data16)) {
    fprintf(stderr, "Couldn't read format\n");
    return NULL;
  }
  *format = (short)data16;
  if (readShort(file, &data16)) {
    fprintf(stderr, "Couldn't read channels\n");
    return NULL;
  }
  *channels = (short)data16;
  if (readLong(file, &data32)) {
    fprintf(stderr, "Couldn't read speed\n");
    return NULL;
  }
  *speed = (long)data32;
  if (readLong(file, &bytesPerSec)) {
    fprintf(stderr, "Couldn't read bytes per second\n");
    return NULL;
  }
  if (readShort(file, &blockAlign)) {
    fprintf(stderr, "Couldn't read block alignment\n");
    return NULL;
  }
  if (readShort(file, &bitsPerSample)) {
    fprintf(stderr, "Couldn't read bits per sample\n");
    return NULL;
  }
  if (bitsPerSample==8) *width=1;
  else if (bitsPerSample==16) *width=2;
  else if (bitsPerSample==32) *width=4;
  else return NULL;

  // go find the data
  skipChunk(file, len - 16);
  if (findChunk(file, "data", &len)) {
    fprintf(stderr, "Failed to find the the data in WAVE\n");
    return NULL;
  }
  *samples = (int)(len / (int32_t)(*width) / (int32_t)(*channels));

  closer.release();
  return file;
}
void QWaveDecoder::handleData()
{
    // As a special "state", if we have junk to skip, we do
    if (junkToSkip > 0) {
        discardBytes(junkToSkip); // this also updates junkToSkip

        // If we couldn't skip all the junk, return
        if (junkToSkip > 0) {
            // We might have run out
            if (source->atEnd())
                parsingFailed();
            return;
        }
    }

    if (state == QWaveDecoder::InitialState) {
        if (source->bytesAvailable() < qint64(sizeof(RIFFHeader)))
            return;

        RIFFHeader riff;
        source->read(reinterpret_cast<char *>(&riff), sizeof(RIFFHeader));

        // RIFF = little endian RIFF, RIFX = big endian RIFF
        if (((qstrncmp(riff.descriptor.id, "RIFF", 4) != 0) && (qstrncmp(riff.descriptor.id, "RIFX", 4) != 0))
                || qstrncmp(riff.type, "WAVE", 4) != 0) {
            parsingFailed();
            return;
        } else {
            state = QWaveDecoder::WaitingForFormatState;
            if (qstrncmp(riff.descriptor.id, "RIFX", 4) == 0)
                bigEndian = true;
            else
                bigEndian = false;
        }
    }

    if (state == QWaveDecoder::WaitingForFormatState) {
        if (findChunk("fmt ")) {
            chunk descriptor;
            peekChunk(&descriptor);

            quint32 rawChunkSize = descriptor.size + sizeof(chunk);
            if (source->bytesAvailable() < qint64(rawChunkSize))
                return;

            WAVEHeader wave;
            source->read(reinterpret_cast<char *>(&wave), sizeof(WAVEHeader));

            if (rawChunkSize > sizeof(WAVEHeader))
                discardBytes(rawChunkSize - sizeof(WAVEHeader));

            // Swizzle this
            if (bigEndian) {
                wave.audioFormat = qFromBigEndian<quint16>(wave.audioFormat);
            } else {
                wave.audioFormat = qFromLittleEndian<quint16>(wave.audioFormat);
            }

            if (wave.audioFormat != 0 && wave.audioFormat != 1) {
                // 32bit wave files have format == 0xFFFE (WAVE_FORMAT_EXTENSIBLE).
                // but don't support them at the moment.
                parsingFailed();
                return;
            } else {
                format.setCodec(QLatin1String("audio/pcm"));

                if (bigEndian) {
                    int bps = qFromBigEndian<quint16>(wave.bitsPerSample);

                    format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
                    format.setByteOrder(QAudioFormat::BigEndian);
                    format.setSampleRate(qFromBigEndian<quint32>(wave.sampleRate));
                    format.setSampleSize(bps);
                    format.setChannelCount(qFromBigEndian<quint16>(wave.numChannels));
                } else {
                    int bps = qFromLittleEndian<quint16>(wave.bitsPerSample);

                    format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
                    format.setByteOrder(QAudioFormat::LittleEndian);
                    format.setSampleRate(qFromLittleEndian<quint32>(wave.sampleRate));
                    format.setSampleSize(bps);
                    format.setChannelCount(qFromLittleEndian<quint16>(wave.numChannels));
                }

                state = QWaveDecoder::WaitingForDataState;
            }
        }
    }

    if (state == QWaveDecoder::WaitingForDataState) {
        if (findChunk("data")) {
            source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));

            chunk descriptor;
            source->read(reinterpret_cast<char *>(&descriptor), sizeof(chunk));
            if (bigEndian)
                descriptor.size = qFromBigEndian<quint32>(descriptor.size);
            else
                descriptor.size = qFromLittleEndian<quint32>(descriptor.size);

            dataSize = descriptor.size;

            haveFormat = true;
            connect(source, SIGNAL(readyRead()), SIGNAL(readyRead()));
            emit formatKnown();

            return;
        }
    }

    // If we hit the end without finding data, it's a parsing error
    if (source->atEnd()) {
        parsingFailed();
    }
}
Пример #8
0
int32_t WavStreamer::openFile(const QString &filename)
{
    if (m_waveStream != 0)
    {
        delete m_waveStream;
        m_waveStream = 0;
    }

    if (m_file.isOpen())
    {
        m_file.close();
    }

    m_isOK = false;

    // try to open the file
    m_file.setFileName(filename);
    if (m_file.open(QIODevice::ReadOnly) == false)
    {
        return -2;  // error opening file
    }

    m_waveStream = new QDataStream(&m_file);

    // check for RIFF file & size
    size_t bytes = m_waveStream->readRawData(m_chunkType, 4);
    if ((bytes != 4) || (strncmp(m_chunkType, "RIFF", 4)!=0))
    {
        delete m_waveStream;
        m_waveStream = NULL;
        m_file.close();
        return -1;
    }

    bytes = m_waveStream->readRawData((char*)&m_chunkSize, 4);
    if (bytes != 4)
    {
        delete m_waveStream;
        m_waveStream = NULL;
        m_file.close();
        return -1;
    }

    bytes = m_waveStream->readRawData((char*)&m_chunkType, 4);
    if ((bytes != 4) && (strncmp(m_chunkType, "WAVE", 4)!=0))
    {
        delete m_waveStream;
        m_waveStream = NULL;
        m_file.close();
        return -1;
    }

    m_riffSize = m_chunkSize + 8; // size of RIFF chunk + 4-byte ID + 4-byte chunksize.
    if (!findChunk("fmt "))
    {
        // error, format chunk not found!
        delete m_waveStream;
        m_waveStream = NULL;
        m_file.close();
        return -1;
    }

    // now, read the format chunk
    bytes = m_waveStream->readRawData((char*)&m_waveFormat, sizeof(WavFormatChunk));
    if (m_waveFormat.wFormatTag == 65534)  // WAVE_FORMAT_EXTENSIBLE case..
    {
        m_waveFormat.wFormatTag = 1;  // treat as PCM data, which should be the same when we have only 2 channels.
    }

    if (((m_waveFormat.wFormatTag != 3) && (m_waveFormat.wFormatTag != 1)) || (m_waveFormat.wChannels != 2))
    {
        delete m_waveStream;
        m_waveStream = NULL;
        m_file.close();
        return -1;  // wrong format!
    }
    // formats smaller than 16 bits are not supported!
    if (m_waveFormat.wBitsPerSample < 16)
    {
        delete m_waveStream;
        m_waveStream = NULL;
        m_file.close();
        return -1;
    }

    // if there are additional bytes in the format chunk, skip them.
    // important in the WAVE_FORMAT_EXTENSIBLE case!
    if (sizeof(WavFormatChunk) != m_chunkSize)
    {
        m_waveStream->skipRawData(m_chunkSize - sizeof(WavFormatChunk));
    }

    // now, search for the audio data and set the file offset pointers
    if (!findChunk("data"))
    {
        delete m_waveStream;
        m_waveStream = NULL;
        m_file.close();
        return -1;
    }

    m_playStart  = m_waveStream->device()->pos();
    m_playOffset = m_playStart;
    m_playEnd    = m_playStart + m_chunkSize;

    // allocate the correct temporary buffer.
    if (tempBuffer!=NULL) delete[] static_cast<char*>(tempBuffer);
    tempBuffer = static_cast<void*>(new char[m_waveFormat.wBitsPerSample*TEMPBUFFERSIZE*2/8]);

    // don't forget to actually read the data
    readRawData(TEMPBUFFERSIZE);
    sampleIndex = 0;

    m_filename = filename;
    m_isOK = true;
    return 0;
}
Пример #9
0
void QWaveDecoder::handleData()
{
    if (state == QWaveDecoder::InitialState) {
        if (source->bytesAvailable() < qint64(sizeof(RIFFHeader)))
            return;

        RIFFHeader riff;
        source->read(reinterpret_cast<char *>(&riff), sizeof(RIFFHeader));

        if (qstrncmp(riff.descriptor.id, "RIFF", 4) != 0 ||
            qstrncmp(riff.type, "WAVE", 4) != 0) {
            source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
            emit invalidFormat();

            return;
        } else {
            state = QWaveDecoder::WaitingForFormatState;
        }
    }

    if (state == QWaveDecoder::WaitingForFormatState) {
        if (findChunk("fmt ")) {
            chunk descriptor;
            source->peek(reinterpret_cast<char *>(&descriptor), sizeof(chunk));

            if (source->bytesAvailable() < qint64(descriptor.size + sizeof(chunk)))
                return;

            WAVEHeader wave;
            source->read(reinterpret_cast<char *>(&wave), sizeof(WAVEHeader));
            if (descriptor.size > sizeof(WAVEHeader))
                discardBytes(descriptor.size - sizeof(WAVEHeader));

            if (wave.audioFormat != 0 && wave.audioFormat != 1) {
                source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
                emit invalidFormat();

                return;
            } else {
                int bps = qFromLittleEndian<quint16>(wave.bitsPerSample);

                format.setCodec(QLatin1String("audio/pcm"));
                format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
                format.setByteOrder(QAudioFormat::LittleEndian);
                format.setFrequency(qFromLittleEndian<quint32>(wave.sampleRate));
                format.setSampleSize(bps);
                format.setChannels(qFromLittleEndian<quint16>(wave.numChannels));

                state = QWaveDecoder::WaitingForDataState;
            }
        }
    }

    if (state == QWaveDecoder::WaitingForDataState) {
        if (findChunk("data")) {
            source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));

            chunk descriptor;
            source->read(reinterpret_cast<char *>(&descriptor), sizeof(chunk));
            dataSize = descriptor.size;

            haveFormat = true;
            connect(source, SIGNAL(readyRead()), SIGNAL(readyRead()));
            emit formatKnown();

            return;
        }
    }

    if (source->atEnd()) {
        source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData()));
        emit invalidFormat();

        return;
    }

}