1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 15:02:34 +02:00

Remove dependency on libMAD (hurrah!)

This commit is contained in:
darkf 2017-09-13 12:02:45 -05:00 committed by Daniel Evans
parent 4f60dcb663
commit 8e26431665
7 changed files with 0 additions and 240 deletions

View File

@ -84,7 +84,6 @@ endif()
find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED)
find_package(Bullet REQUIRED)
find_package(MAD REQUIRED)
find_package(GLM REQUIRED)
find_package(LibSndFile REQUIRED)
find_package(FFmpeg REQUIRED)

View File

@ -19,8 +19,6 @@ set(RWENGINE_SOURCES
src/ai/PlayerController.hpp
src/ai/TrafficDirector.cpp
src/ai/TrafficDirector.hpp
src/audio/MADStream.cpp
src/audio/MADStream.hpp
src/audio/SoundManager.cpp
src/audio/SoundManager.hpp
src/audio/alCheck.cpp
@ -143,7 +141,6 @@ endif()
target_link_libraries(rwengine
rwlib
${MAD_LIBRARY}
${LIBSNDFILE_LIBRARY}
${FFMPEG_LIBRARIES}
${OPENAL_LIBRARY}
@ -152,7 +149,6 @@ target_link_libraries(rwengine
include_directories(SYSTEM
${BULLET_INCLUDE_DIR}
${MAD_INCLUDE_DIR}
${LIBSNDFILE_INCLUDE_DIR}
${FFMPEG_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR}

View File

@ -1,171 +0,0 @@
#include "audio/MADStream.hpp"
#include <thread>
inline signed int MADStream::scale(mad_fixed_t sample) {
/* round */
sample += (1L << (MAD_F_FRACBITS - 16));
/* clip */
if (sample >= MAD_F_ONE) {
sample = MAD_F_ONE - 1;
} else if (sample < -MAD_F_ONE) {
sample = -MAD_F_ONE;
}
/* quantize */
return sample >> (MAD_F_FRACBITS + 1 - 16);
}
mad_flow MADStream::ms_header(void* user, mad_header const* header) {
MADStream* stream = static_cast<MADStream*>(user);
stream->mMadSampleRate = header->samplerate;
// see enum mad_mode
stream->mMadChannels = header->mode + 1;
return MAD_FLOW_CONTINUE;
}
mad_flow MADStream::ms_input(void* user, mad_stream* stream) {
MADStream* self = static_cast<MADStream*>(user);
if (!self->mReadProgress) {
return MAD_FLOW_STOP;
}
auto rd = self->mReadProgress;
self->mReadProgress = 0;
mad_stream_buffer(stream, self->mFdm, rd);
return MAD_FLOW_CONTINUE;
}
mad_flow MADStream::ms_output(void* user, mad_header const* header,
mad_pcm* pcm) {
RW_UNUSED(header);
MADStream* self = static_cast<MADStream*>(user);
if (self->stopped) {
return MAD_FLOW_STOP;
}
if (!self->numFreeBuffers) {
ALint buffersProcessed;
do {
/**
* Sleep a bit while waiting for OpenAL buffers to become available.
* The number is arbitrary and depends on the size of the
* buffer/audio samples,
* as well as how quickly the computer can feed more buffers into
* OpenAL.
*/
std::this_thread::sleep_for(std::chrono::milliseconds(20));
alGetSourcei(self->alSource, AL_BUFFERS_PROCESSED,
&buffersProcessed);
} while (buffersProcessed <= 0);
alCheck(alSourceUnqueueBuffers(self->alSource, buffersProcessed,
self->unqueuedBuffers));
self->numFreeBuffers += buffersProcessed;
}
int nsamples = pcm->length;
mad_fixed_t const *left, *right;
left = pcm->samples[0];
right = pcm->samples[1];
int s = 0;
while (nsamples--) {
signed int sample = *left++;
self->mCurrentSamples.push_back(scale(sample));
sample = *right++;
self->mCurrentSamples.push_back(scale(sample));
s++;
}
alCheck(alBufferData(self->buffers[self->currentBuffer], AL_FORMAT_STEREO16,
self->mCurrentSamples.data(),
self->mCurrentSamples.size() * sizeof(uint16_t),
pcm->samplerate));
alCheck(alSourceQueueBuffers(self->alSource, 1,
self->buffers + self->currentBuffer));
self->mCurrentSamples.clear();
self->currentBuffer++;
self->currentBuffer %= numALbuffers;
self->numFreeBuffers--;
return MAD_FLOW_CONTINUE;
}
mad_flow MADStream::ms_error(void* user, mad_stream* stream, mad_frame* frame) {
RW_UNUSED(user);
RW_UNUSED(frame);
std::cerr << "libmad error: " << mad_stream_errorstr(stream) << std::endl;
return MAD_FLOW_BREAK;
}
MADStream::MADStream() : mFdm(nullptr) {
alCheck(alGenBuffers(numALbuffers, buffers));
alCheck(alGenSources(1, &alSource));
}
MADStream::~MADStream() {
if (mFdm) {
munmap(mFdm, mStat.st_size);
mad_decoder_finish(&mDecoder);
}
}
bool MADStream::openFromFile(const std::string& loc) {
if (mFdm) {
munmap(mFdm, mStat.st_size);
mCurrentSamples.clear();
mad_decoder_finish(&mDecoder);
}
int fd = ::open(loc.c_str(), O_RDONLY);
if (fstat(fd, &mStat) == -1 || mStat.st_size == 0) {
std::cerr << "Fstat failed (" << loc << ")" << std::endl;
return false;
}
void* m = mmap(0, mStat.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (m == MAP_FAILED) {
std::cerr << "mmap failed (" << loc << ")" << std::endl;
return false;
}
mFdm = (unsigned char*)m;
mReadProgress = mStat.st_size;
mad_decoder_init(&mDecoder, this, ms_input, ms_header, 0, ms_output,
ms_error, 0);
new std::thread(
[&]() { mad_decoder_run(&mDecoder, MAD_DECODER_MODE_SYNC); });
alCheck(alSourcef(alSource, AL_PITCH, 1));
alCheck(alSourcef(alSource, AL_GAIN, 1));
alCheck(alSource3f(alSource, AL_POSITION, 0, 0, 0));
alCheck(alSource3f(alSource, AL_VELOCITY, 0, 0, 0));
alCheck(alSourcei(alSource, AL_LOOPING, AL_FALSE));
return true;
}
void MADStream::play() {
alCheck(alSourcePlay(alSource));
}
void MADStream::stop() {
stopped = true;
alCheck(alSourcePlay(alSource));
}

View File

@ -1,59 +0,0 @@
#pragma once
#ifndef _MADSTREAM_HPP_
#define _MADSTREAM_HPP_
#include "al.h"
#include "alc.h"
#include <fcntl.h>
#include <mad.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>
#include <rw/defines.hpp>
#include "audio/alCheck.hpp"
#include <vector>
class MADStream {
mad_decoder mDecoder;
unsigned int mMadSampleRate;
unsigned int mMadChannels;
unsigned char* mFdm;
struct stat mStat;
unsigned int mReadProgress;
std::vector<int16_t> mCurrentSamples;
/**
* The number of OpenAL buffers is arbitrary, but due to the kind of small
* buffer/audio sample size, we need a bunch of them so the computer can
* keep up with filling them.
*/
constexpr static size_t numALbuffers = 8;
ALuint buffers[numALbuffers];
ALuint unqueuedBuffers[numALbuffers];
size_t numFreeBuffers = numALbuffers;
size_t currentBuffer = 0;
ALuint alSource;
bool stopped = false;
static inline signed int scale(mad_fixed_t sample);
static mad_flow ms_header(void* user, mad_header const* header);
static mad_flow ms_input(void* user, mad_stream* stream);
static mad_flow ms_output(void* user, mad_header const* header,
mad_pcm* pcm);
static mad_flow ms_error(void* user, mad_stream* stream, mad_frame* frame);
public:
MADStream();
~MADStream();
bool openFromFile(const std::string& loc);
void play();
void stop();
};
#endif

View File

@ -1,7 +1,5 @@
#include <audio/MADStream.hpp>
#include <audio/SoundManager.hpp>
#include "audio/MADStream.hpp"
#include "audio/alCheck.hpp"
extern "C" {

View File

@ -7,8 +7,6 @@
#include <string>
#include <vector>
class MADStream;
class SoundManager {
public:
SoundManager();

View File

@ -17,7 +17,6 @@ class Logger;
#include <objects/VehicleInfo.hpp>
#include <rw/types.hpp>
#include <audio/MADStream.hpp>
#include <gl/TextureData.hpp>
#include <platform/FileIndex.hpp>