add missing files after merging

This commit is contained in:
Xiao Xiangquan 2011-09-05 14:44:11 +00:00
parent d31d7fd487
commit 034cda72d3
41 changed files with 40542 additions and 0 deletions

@ -0,0 +1,42 @@
/*
* $Id: AUD_DynamicIIRFilterFactory.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
* \ingroup audfx
*/
#include "AUD_DynamicIIRFilterFactory.h"
#include "AUD_DynamicIIRFilterReader.h"
AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
AUD_Reference<AUD_IReader> AUD_DynamicIIRFilterFactory::createReader()
{
return new AUD_DynamicIIRFilterReader(getReader(), this);
}

@ -0,0 +1,65 @@
/*
* $Id: AUD_DynamicIIRFilterFactory.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/FX/AUD_DynamicIIRFilterFactory.h
* \ingroup audfx
*/
#ifndef AUD_DYNAMICIIRFILTERFACTORY
#define AUD_DYNAMICIIRFILTERFACTORY
#include "AUD_EffectFactory.h"
#include <vector>
/**
* This factory creates a IIR filter reader.
*
* This means that on sample rate change the filter recalculates its
* coefficients.
*/
class AUD_DynamicIIRFilterFactory : public AUD_EffectFactory
{
public:
/**
* Creates a new Dynmic IIR filter factory.
* \param factory The input factory.
*/
AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory);
virtual AUD_Reference<AUD_IReader> createReader();
/**
* Recalculates the filter coefficients.
* \param rate The sample rate of the audio data.
* \param[out] b The input filter coefficients.
* \param[out] a The output filter coefficients.
*/
virtual void recalculateCoefficients(AUD_SampleRate rate,
std::vector<float>& b,
std::vector<float>& a)=0;
};
#endif // AUD_DYNAMICIIRFILTERFACTORY

@ -0,0 +1,45 @@
/*
* $Id: AUD_DynamicIIRFilterReader.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/FX/AUD_DynamicIIRFilterReader.cpp
* \ingroup audfx
*/
#include "AUD_DynamicIIRFilterReader.h"
AUD_DynamicIIRFilterReader::AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader> reader,
AUD_Reference<AUD_DynamicIIRFilterFactory> factory) :
AUD_IIRFilterReader(reader, std::vector<float>(), std::vector<float>())
{
sampleRateChanged(reader->getSpecs().rate);
}
void AUD_DynamicIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
{
std::vector<float> a, b;
m_factory->recalculateCoefficients(rate, b, a);
setCoefficients(b, a);
}

@ -0,0 +1,56 @@
/*
* $Id: AUD_DynamicIIRFilterReader.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/FX/AUD_DynamicIIRFilterReader.h
* \ingroup audfx
*/
#ifndef AUD_DYNAMICIIRFILTERREADER
#define AUD_DYNAMICIIRFILTERREADER
#include "AUD_IIRFilterReader.h"
#include "AUD_DynamicIIRFilterFactory.h"
/**
* This class is for dynamic infinite impulse response filters with simple
* coefficients that change depending on the sample rate.
*/
class AUD_DynamicIIRFilterReader : public AUD_IIRFilterReader
{
private:
/**
* The factory for dynamically recalculating filter coefficients.
*/
AUD_Reference<AUD_DynamicIIRFilterFactory> m_factory;
public:
AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader> reader,
AUD_Reference<AUD_DynamicIIRFilterFactory> factory);
virtual void sampleRateChanged(AUD_SampleRate rate);
};
#endif // AUD_DYNAMICIIRFILTERREADER

@ -0,0 +1,305 @@
/*
* $Id: AUD_FFMPEGWriter.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
* \ingroup audffmpeg
*/
// needed for INT64_C
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "AUD_FFMPEGWriter.h"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include "ffmpeg_compat.h"
}
static const char* context_error = "AUD_FFMPEGWriter: Couldn't allocate context.";
static const char* codec_error = "AUD_FFMPEGWriter: Invalid codec or codec not found.";
static const char* stream_error = "AUD_FFMPEGWriter: Couldn't allocate stream.";
static const char* format_error = "AUD_FFMPEGWriter: Unsupported sample format.";
static const char* file_error = "AUD_FFMPEGWriter: File couldn't be written.";
static const char* write_error = "AUD_FFMPEGWriter: Error writing packet.";
AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate) :
m_position(0),
m_specs(specs),
m_input_samples(0)
{
static const char* formats[] = { NULL, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
if(avformat_alloc_output_context2(&m_formatCtx, NULL, formats[format], filename.c_str()))
AUD_THROW(AUD_ERROR_FFMPEG, context_error);
m_outputFmt = m_formatCtx->oformat;
switch(codec)
{
case AUD_CODEC_AAC:
m_outputFmt->audio_codec = CODEC_ID_AAC;
break;
case AUD_CODEC_AC3:
m_outputFmt->audio_codec = CODEC_ID_AC3;
break;
case AUD_CODEC_FLAC:
m_outputFmt->audio_codec = CODEC_ID_FLAC;
break;
case AUD_CODEC_MP2:
m_outputFmt->audio_codec = CODEC_ID_MP2;
break;
case AUD_CODEC_MP3:
m_outputFmt->audio_codec = CODEC_ID_MP3;
break;
case AUD_CODEC_PCM:
switch(specs.format)
{
case AUD_FORMAT_U8:
m_outputFmt->audio_codec = CODEC_ID_PCM_U8;
break;
case AUD_FORMAT_S16:
m_outputFmt->audio_codec = CODEC_ID_PCM_S16LE;
break;
case AUD_FORMAT_S24:
m_outputFmt->audio_codec = CODEC_ID_PCM_S24LE;
break;
case AUD_FORMAT_S32:
m_outputFmt->audio_codec = CODEC_ID_PCM_S32LE;
break;
case AUD_FORMAT_FLOAT32:
m_outputFmt->audio_codec = CODEC_ID_PCM_F32LE;
break;
case AUD_FORMAT_FLOAT64:
m_outputFmt->audio_codec = CODEC_ID_PCM_F64LE;
break;
default:
m_outputFmt->audio_codec = CODEC_ID_NONE;
break;
}
break;
case AUD_CODEC_VORBIS:
m_outputFmt->audio_codec = CODEC_ID_VORBIS;
break;
default:
m_outputFmt->audio_codec = CODEC_ID_NONE;
break;
}
try
{
if(m_outputFmt->audio_codec == CODEC_ID_NONE)
AUD_THROW(AUD_ERROR_SPECS, codec_error);
m_stream = av_new_stream(m_formatCtx, 0);
if(!m_stream)
AUD_THROW(AUD_ERROR_FFMPEG, stream_error);
m_codecCtx = m_stream->codec;
m_codecCtx->codec_id = m_outputFmt->audio_codec;
m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
m_codecCtx->bit_rate = bitrate;
m_codecCtx->sample_rate = int(m_specs.rate);
m_codecCtx->channels = m_specs.channels;
m_codecCtx->time_base.num = 1;
m_codecCtx->time_base.den = m_codecCtx->sample_rate;
switch(m_specs.format)
{
case AUD_FORMAT_U8:
m_convert = AUD_convert_float_u8;
m_codecCtx->sample_fmt = SAMPLE_FMT_U8;
break;
case AUD_FORMAT_S16:
m_convert = AUD_convert_float_s16;
m_codecCtx->sample_fmt = SAMPLE_FMT_S16;
break;
case AUD_FORMAT_S32:
m_convert = AUD_convert_float_s32;
m_codecCtx->sample_fmt = SAMPLE_FMT_S32;
break;
case AUD_FORMAT_FLOAT32:
m_convert = AUD_convert_copy<float>;
m_codecCtx->sample_fmt = SAMPLE_FMT_FLT;
break;
case AUD_FORMAT_FLOAT64:
m_convert = AUD_convert_float_double;
m_codecCtx->sample_fmt = SAMPLE_FMT_DBL;
break;
default:
AUD_THROW(AUD_ERROR_FFMPEG, format_error);
}
try
{
if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
AVCodec* codec = avcodec_find_encoder(m_codecCtx->codec_id);
if(!codec)
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
if(avcodec_open(m_codecCtx, codec))
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
m_output_buffer.resize(FF_MIN_BUFFER_SIZE);
int samplesize = AUD_MAX(AUD_SAMPLE_SIZE(m_specs), AUD_DEVICE_SAMPLE_SIZE(m_specs));
if(m_codecCtx->frame_size <= 1)
m_input_size = 0;
else
{
m_input_buffer.resize(m_codecCtx->frame_size * samplesize);
m_input_size = m_codecCtx->frame_size;
}
try
{
if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
AUD_THROW(AUD_ERROR_FILE, file_error);
avformat_write_header(m_formatCtx, NULL);
}
catch(AUD_Exception&)
{
avcodec_close(m_codecCtx);
av_freep(&m_formatCtx->streams[0]->codec);
throw;
}
}
catch(AUD_Exception&)
{
av_freep(&m_formatCtx->streams[0]);
throw;
}
}
catch(AUD_Exception&)
{
av_free(m_formatCtx);
throw;
}
}
AUD_FFMPEGWriter::~AUD_FFMPEGWriter()
{
// writte missing data
if(m_input_samples)
{
sample_t* buf = m_input_buffer.getBuffer();
memset(buf + m_specs.channels * m_input_samples, 0,
(m_input_size - m_input_samples) * AUD_DEVICE_SAMPLE_SIZE(m_specs));
encode(buf);
}
av_write_trailer(m_formatCtx);
avcodec_close(m_codecCtx);
av_freep(&m_formatCtx->streams[0]->codec);
av_freep(&m_formatCtx->streams[0]);
avio_close(m_formatCtx->pb);
av_free(m_formatCtx);
}
int AUD_FFMPEGWriter::getPosition() const
{
return m_position;
}
AUD_DeviceSpecs AUD_FFMPEGWriter::getSpecs() const
{
return m_specs;
}
void AUD_FFMPEGWriter::encode(sample_t* data)
{
sample_t* outbuf = m_output_buffer.getBuffer();
// convert first
if(m_input_size)
m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_size * m_specs.channels);
AVPacket packet;
av_init_packet(&packet);
packet.size = avcodec_encode_audio(m_codecCtx, reinterpret_cast<uint8_t*>(outbuf), m_output_buffer.getSize(), reinterpret_cast<short*>(data));
if(m_codecCtx->coded_frame && m_codecCtx->coded_frame->pts != AV_NOPTS_VALUE)
packet.pts = av_rescale_q(m_codecCtx->coded_frame->pts, m_codecCtx->time_base, m_stream->time_base);
packet.flags |= AV_PKT_FLAG_KEY;
packet.stream_index = m_stream->index;
packet.data = reinterpret_cast<uint8_t*>(outbuf);
if(av_interleaved_write_frame(m_formatCtx, &packet))
AUD_THROW(AUD_ERROR_FFMPEG, write_error);
}
void AUD_FFMPEGWriter::write(unsigned int length, sample_t* buffer)
{
unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
if(m_input_size)
{
sample_t* inbuf = m_input_buffer.getBuffer();
while(length)
{
unsigned int len = AUD_MIN(m_input_size - m_input_samples, length);
memcpy(inbuf + m_input_samples * m_specs.channels, buffer, len * samplesize);
buffer += len * m_specs.channels;
m_input_samples += len;
m_position += len;
length -= len;
if(m_input_samples == m_input_size)
{
encode(inbuf);
m_input_samples = 0;
}
}
}
else // PCM data, can write directly!
{
int samplesize = AUD_SAMPLE_SIZE(m_specs);
if(m_output_buffer.getSize() != length * m_specs.channels * m_codecCtx->bits_per_coded_sample / 8)
m_output_buffer.resize(length * m_specs.channels * m_codecCtx->bits_per_coded_sample / 8);
m_input_buffer.assureSize(length * AUD_MAX(AUD_DEVICE_SAMPLE_SIZE(m_specs), samplesize));
sample_t* buf = m_input_buffer.getBuffer();
m_convert(reinterpret_cast<data_t*>(buf), reinterpret_cast<data_t*>(buffer), length * m_specs.channels);
encode(buf);
m_position += length;
}
}

@ -0,0 +1,140 @@
/*
* $Id: AUD_FFMPEGWriter.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/ffmpeg/AUD_FFMPEGWriter.h
* \ingroup audffmpeg
*/
#ifndef AUD_FFMPEGWRITER
#define AUD_FFMPEGWRITER
#include "AUD_ConverterFunctions.h"
#include "AUD_Buffer.h"
#include "AUD_IWriter.h"
#include <string>
struct AVCodecContext;
extern "C" {
#include <libavformat/avformat.h>
}
/**
* This class writes a sound file via ffmpeg.
*/
class AUD_FFMPEGWriter : public AUD_IWriter
{
private:
/**
* The current position in samples.
*/
int m_position;
/**
* The specification of the audio data.
*/
AUD_DeviceSpecs m_specs;
/**
* The AVFormatContext structure for using ffmpeg.
*/
AVFormatContext* m_formatCtx;
/**
* The AVCodecContext structure for using ffmpeg.
*/
AVCodecContext* m_codecCtx;
/**
* The AVOutputFormat structure for using ffmpeg.
*/
AVOutputFormat* m_outputFmt;
/**
* The AVStream structure for using ffmpeg.
*/
AVStream* m_stream;
/**
* The input buffer for the format converted data before encoding.
*/
AUD_Buffer m_input_buffer;
/**
* The output buffer for the encoded audio data.
*/
AUD_Buffer m_output_buffer;
/**
* The count of input samples we have so far.
*/
unsigned int m_input_samples;
/**
* The count of input samples necessary to encode a packet.
*/
unsigned int m_input_size;
/**
* Converter function.
*/
AUD_convert_f m_convert;
// hide copy constructor and operator=
AUD_FFMPEGWriter(const AUD_FFMPEGWriter&);
AUD_FFMPEGWriter& operator=(const AUD_FFMPEGWriter&);
/**
* Encodes to the output buffer.
* \param data Pointer to the data to encode.
*/
void encode(sample_t* data);
public:
/**
* Creates a new writer.
* \param filename The path to the file to be read.
* \param specs The file's audio specification.
* \param format The file's container format.
* \param codec The codec used for encoding the audio data.
* \param bitrate The bitrate for encoding.
* \exception AUD_Exception Thrown if the file specified does not exist or
* cannot be read with ffmpeg.
*/
AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
/**
* Destroys the writer and closes the file.
*/
virtual ~AUD_FFMPEGWriter();
virtual int getPosition() const;
virtual AUD_DeviceSpecs getSpecs() const;
virtual void write(unsigned int length, sample_t* buffer);
};
#endif //AUD_FFMPEGWRITER

@ -0,0 +1,159 @@
/*
* $Id: AUD_AnimateableProperty.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_AnimateableProperty.cpp
* \ingroup audaspaceintern
*/
#include "AUD_AnimateableProperty.h"
#include <cstring>
#include <cmath>
AUD_AnimateableProperty::AUD_AnimateableProperty(int count) :
AUD_Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
{
memset(getBuffer(), 0, count * sizeof(float));
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&m_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
AUD_AnimateableProperty::~AUD_AnimateableProperty()
{
pthread_mutex_destroy(&m_mutex);
}
void AUD_AnimateableProperty::lock()
{
pthread_mutex_lock(&m_mutex);
}
void AUD_AnimateableProperty::unlock()
{
pthread_mutex_unlock(&m_mutex);
}
void AUD_AnimateableProperty::write(const float* data)
{
lock();
m_isAnimated = false;
memcpy(getBuffer(), data, m_count * sizeof(float));
unlock();
}
void AUD_AnimateableProperty::write(const float* data, int position, int count)
{
lock();
m_isAnimated = true;
int pos = getSize() / (sizeof(float) * m_count);
assureSize((count + position) * m_count * sizeof(float), true);
float* buf = getBuffer();
memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
for(int i = pos; i < position; i++)
memcpy(buf + i * m_count, buf + (pos - 1) * m_count, m_count * sizeof(float));
unlock();
}
void AUD_AnimateableProperty::read(float position, float* out)
{
lock();
if(!m_isAnimated)
{
memcpy(out, getBuffer(), m_count * sizeof(float));
unlock();
return;
}
int last = getSize() / (sizeof(float) * m_count) - 1;
float t = position - floor(position);
if(position >= last)
{
position = last;
t = 0;
}
if(t == 0)
{
memcpy(out, getBuffer() + int(floor(position)) * m_count, m_count * sizeof(float));
}
else
{
int pos = int(floor(position)) * m_count;
float t2 = t * t;
float t3 = t2 * t;
float m0, m1;
float* p0;
float* p1 = getBuffer() + pos;
float* p2;
float* p3;
last *= m_count;
if(pos == 0)
p0 = p1;
else
p0 = p1 - m_count;
p2 = p1 + m_count;
if(pos + m_count == last)
p3 = p2;
else
p3 = p2 + m_count;
for(int i = 0; i < m_count; i++)
{
m0 = (p2[i] - p0[i]) / 2.0f;
m1 = (p3[i] - p1[i]) / 2.0f;
out[i] = (2 * t3 - 3 * t2 + 1) * p0[i] + (-2 * t3 + 3 * t2) * p1[i] +
(t3 - 2 * t2 + t) * m0 + (t3 - t2) * m1;
}
}
unlock();
}
bool AUD_AnimateableProperty::isAnimated() const
{
return m_isAnimated;
}

@ -0,0 +1,108 @@
/*
* $Id: AUD_AnimateableProperty.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_AnimateableProperty.h
* \ingroup audaspaceintern
*/
#ifndef AUD_ANIMATEABLEPROPERTY
#define AUD_ANIMATEABLEPROPERTY
#include "AUD_Buffer.h"
#include <pthread.h>
/**
* This class saves animation data for float properties.
*/
class AUD_AnimateableProperty : private AUD_Buffer
{
private:
/// The count of floats for a single property.
const int m_count;
/// Whether the property is animated or not.
bool m_isAnimated;
/// The mutex for locking.
pthread_mutex_t m_mutex;
// hide copy constructor and operator=
AUD_AnimateableProperty(const AUD_AnimateableProperty&);
AUD_AnimateableProperty& operator=(const AUD_AnimateableProperty&);
public:
/**
* Creates a new animateable property.
* \param count The count of floats for a single property.
*/
AUD_AnimateableProperty(int count = 1);
/**
* Destroys the animateable property.
*/
~AUD_AnimateableProperty();
/**
* Locks the property.
*/
void lock();
/**
* Unlocks the previously locked property.
*/
void unlock();
/**
* Writes the properties value and marks it non-animated.
* \param data The new value.
*/
void write(const float* data);
/**
* Writes the properties value and marks it animated.
* \param data The new value.
* \param position The position in the animation in frames.
* \param count The count of frames to write.
*/
void write(const float* data, int position, int count);
/**
* Reads the properties value.
* \param position The position in the animation in frames.
* \param[out] out Where to write the value to.
*/
void read(float position, float* out);
/**
* Returns whether the property is animated.
* \return Whether the property is animated.
*/
bool isAnimated() const;
};
#endif //AUD_ANIMATEABLEPROPERTY

@ -0,0 +1,97 @@
/*
* $Id: AUD_FileWriter.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_FileWriter.cpp
* \ingroup audaspaceintern
*/
#ifdef WITH_FFMPEG
// needed for INT64_C
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "AUD_FFMPEGWriter.h"
#endif
#ifdef WITH_SNDFILE
#include "AUD_SndFileWriter.h"
#endif
#include "AUD_FileWriter.h"
#include "AUD_Buffer.h"
static const char* write_error = "AUD_FileWriter: File couldn't be written.";
AUD_Reference<AUD_IWriter> AUD_FileWriter::createWriter(std::string filename,AUD_DeviceSpecs specs,
AUD_Container format, AUD_Codec codec, unsigned int bitrate)
{
#ifdef WITH_SNDFILE
try
{
return new AUD_SndFileWriter(filename, specs, format, codec, bitrate);
}
catch(AUD_Exception&) {}
#endif
#ifdef WITH_FFMPEG
try
{
return new AUD_FFMPEGWriter(filename, specs, format, codec, bitrate);
}
catch(AUD_Exception&) {}
#endif
AUD_THROW(AUD_ERROR_SPECS, write_error);
}
void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize)
{
AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs()));
sample_t* buf = buffer.getBuffer();
int len;
bool eos = false;
int channels = writer->getSpecs().channels;
for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
{
len = buffersize;
if((len > length - pos) && (length > 0))
len = length - pos;
reader->read(len, eos, buf);
for(int i = 0; i < len * channels; i++)
{
// clamping!
if(buf[i] > 1)
buf[i] = 1;
else if(buf[i] < -1)
buf[i] = -1;
}
writer->write(len, buf);
}
}

@ -0,0 +1,75 @@
/*
* $Id: AUD_FileWriter.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_FileWriter.h
* \ingroup audaspaceintern
*/
#ifndef AUD_FILEWRITER
#define AUD_FILEWRITER
#include <string>
#include "AUD_Reference.h"
#include "AUD_IWriter.h"
#include "AUD_IReader.h"
/**
* This class is able to create IWriter classes as well as write reads to them.
*/
class AUD_FileWriter
{
private:
// hide default constructor, copy constructor and operator=
AUD_FileWriter();
AUD_FileWriter(const AUD_FileWriter&);
AUD_FileWriter& operator=(const AUD_FileWriter&);
public:
/**
* Creates a new IWriter.
* \param filename The file to write to.
* \param specs The file's audio specification.
* \param format The file's container format.
* \param codec The codec used for encoding the audio data.
* \param bitrate The bitrate for encoding.
* \return The writer to write data to.
*/
static AUD_Reference<AUD_IWriter> createWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
/**
* Writes a reader to a writer.
* \param reader The reader to read from.
* \param writer The writer to write to.
* \param length How many samples should be transfered.
* \param buffersize How many samples should be transfered at once.
*/
static void writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
};
#endif //AUD_FILEWRITER

@ -0,0 +1,218 @@
/*
* $Id: AUD_I3DHandle.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_I3DHandle.h
* \ingroup audaspaceintern
*/
#ifndef AUD_I3DHANDLE
#define AUD_I3DHANDLE
#include "AUD_Space.h"
#include "AUD_3DMath.h"
/**
* This class represents a playback handle for 3D sources.
*/
class AUD_I3DHandle
{
public:
/**
* Destroys the handle.
*/
virtual ~AUD_I3DHandle() {}
/**
* Retrieves the location of a source.
* \return The location.
*/
virtual AUD_Vector3 getSourceLocation()=0;
/**
* Sets the location of a source.
* \param location The new location.
* \return Whether the action succeeded.
*/
virtual bool setSourceLocation(const AUD_Vector3& location)=0;
/**
* Retrieves the velocity of a source.
* \return The velocity.
*/
virtual AUD_Vector3 getSourceVelocity()=0;
/**
* Sets the velocity of a source.
* \param velocity The new velocity.
* \return Whether the action succeeded.
*/
virtual bool setSourceVelocity(const AUD_Vector3& velocity)=0;
/**
* Retrieves the orientation of a source.
* \return The orientation as quaternion.
*/
virtual AUD_Quaternion getSourceOrientation()=0;
/**
* Sets the orientation of a source.
* \param orientation The new orientation as quaternion.
* \return Whether the action succeeded.
*/
virtual bool setSourceOrientation(const AUD_Quaternion& orientation)=0;
/**
* Checks whether the source location, velocity and orientation are relative
* to the listener.
* \return Whether the source is relative.
*/
virtual bool isRelative()=0;
/**
* Sets whether the source location, velocity and orientation are relative
* to the listener.
* \param relative Whether the source is relative.
* \return Whether the action succeeded.
*/
virtual bool setRelative(bool relative)=0;
/**
* Retrieves the maximum volume of a source.
* \return The maximum volume.
*/
virtual float getVolumeMaximum()=0;
/**
* Sets the maximum volume of a source.
* \param volume The new maximum volume.
* \return Whether the action succeeded.
*/
virtual bool setVolumeMaximum(float volume)=0;
/**
* Retrieves the minimum volume of a source.
* \return The minimum volume.
*/
virtual float getVolumeMinimum()=0;
/**
* Sets the minimum volume of a source.
* \param volume The new minimum volume.
* \return Whether the action succeeded.
*/
virtual bool setVolumeMinimum(float volume)=0;
/**
* Retrieves the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \return The maximum distance.
*/
virtual float getDistanceMaximum()=0;
/**
* Sets the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \param distance The new maximum distance.
* \return Whether the action succeeded.
*/
virtual bool setDistanceMaximum(float distance)=0;
/**
* Retrieves the reference distance of a source.
* \return The reference distance.
*/
virtual float getDistanceReference()=0;
/**
* Sets the reference distance of a source.
* \param distance The new reference distance.
* \return Whether the action succeeded.
*/
virtual bool setDistanceReference(float distance)=0;
/**
* Retrieves the attenuation of a source.
* \return The attenuation.
*/
virtual float getAttenuation()=0;
/**
* Sets the attenuation of a source.
* This value is used for distance calculation.
* \param factor The new attenuation.
* \return Whether the action succeeded.
*/
virtual bool setAttenuation(float factor)=0;
/**
* Retrieves the outer angle of the cone of a source.
* \return The outer angle of the cone.
*/
virtual float getConeAngleOuter()=0;
/**
* Sets the outer angle of the cone of a source.
* \param angle The new outer angle of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeAngleOuter(float angle)=0;
/**
* Retrieves the inner angle of the cone of a source.
* \return The inner angle of the cone.
*/
virtual float getConeAngleInner()=0;
/**
* Sets the inner angle of the cone of a source.
* \param angle The new inner angle of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeAngleInner(float angle)=0;
/**
* Retrieves the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \return The outer volume of the cone.
*/
virtual float getConeVolumeOuter()=0;
/**
* Sets the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \param volume The new outer volume of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeVolumeOuter(float volume)=0;
};
#endif //AUD_I3DHANDLE

@ -0,0 +1,181 @@
/*
* $Id: AUD_IHandle.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_IHandle.h
* \ingroup audaspaceintern
*/
#ifndef AUD_IHANDLE
#define AUD_IHANDLE
//#include "AUD_Space.h"
//#include "AUD_Reference.h"
typedef void (*stopCallback)(void*);
/**
* This class represents a playback handles for specific devices.
*/
class AUD_IHandle
{
public:
/**
* Destroys the handle.
*/
virtual ~AUD_IHandle() {}
/**
* Pauses a played back sound.
* \return
* - true if the sound has been paused.
* - false if the sound isn't playing back or the handle is invalid.
*/
virtual bool pause()=0;
/**
* Resumes a paused sound.
* \return
* - true if the sound has been resumed.
* - false if the sound isn't paused or the handle is invalid.
*/
virtual bool resume()=0;
/**
* Stops a played back or paused sound. The handle is definitely invalid
* afterwards.
* \return
* - true if the sound has been stopped.
* - false if the handle is invalid.
*/
virtual bool stop()=0;
/**
* Gets the behaviour of the device for a played back sound when the sound
* doesn't return any more samples.
* \return
* - true if the source will be paused when it's end is reached
* - false if the handle won't kept or is invalid.
*/
virtual bool getKeep()=0;
/**
* Sets the behaviour of the device for a played back sound when the sound
* doesn't return any more samples.
* \param keep True when the source should be paused and not deleted.
* \return
* - true if the behaviour has been changed.
* - false if the handle is invalid.
*/
virtual bool setKeep(bool keep)=0;
/**
* Seeks in a played back sound.
* \param position The new position from where to play back, in seconds.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
* \warning Whether the seek works or not depends on the sound source.
*/
virtual bool seek(float position)=0;
/**
* Retrieves the current playback position of a sound.
* \return The playback position in seconds, or 0.0 if the handle is
* invalid.
*/
virtual float getPosition()=0;
/**
* Returns the status of a played back sound.
* \return
* - AUD_STATUS_INVALID if the sound has stopped or the handle is
*. invalid
* - AUD_STATUS_PLAYING if the sound is currently played back.
* - AUD_STATUS_PAUSED if the sound is currently paused.
* \see AUD_Status
*/
virtual AUD_Status getStatus()=0;
/**
* Retrieves the volume of a playing sound.
* \return The volume.
*/
virtual float getVolume()=0;
/**
* Sets the volume of a playing sound.
* \param volume The volume.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setVolume(float volume)=0;
/**
* Retrieves the pitch of a playing sound.
* \return The pitch.
*/
virtual float getPitch()=0;
/**
* Sets the pitch of a playing sound.
* \param pitch The pitch.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setPitch(float pitch)=0;
/**
* Retrieves the loop count of a playing sound.
* A negative value indicates infinity.
* \return The remaining loop count.
*/
virtual int getLoopCount()=0;
/**
* Sets the loop count of a playing sound.
* A negative value indicates infinity.
* \param count The new loop count.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setLoopCount(int count)=0;
/**
* Sets the callback function that's called when the end of a playing sound
* is reached.
* \param callback The callback function.
* \param data The data that should be passed to the callback function.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0)=0;
};
#endif //AUD_IHandle

@ -0,0 +1,69 @@
/*
* $Id: AUD_IWriter.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_IWriter.h
* \ingroup audaspaceintern
*/
#ifndef AUD_IWRITER
#define AUD_IWRITER
#include "AUD_Space.h"
/**
* This class represents a sound sink where audio data can be written to.
*/
class AUD_IWriter
{
public:
/**
* Destroys the writer.
*/
virtual ~AUD_IWriter(){}
/**
* Returns how many samples have been written so far.
* \return The writing position as sample count. May be negative if unknown.
*/
virtual int getPosition() const=0;
/**
* Returns the specification of the audio data being written into the sink.
* \return The AUD_DeviceSpecs structure.
* \note Regardless of the format the input still has to be float!
*/
virtual AUD_DeviceSpecs getSpecs() const=0;
/**
* Request to write the next length samples out into the sink.
* \param length The count of samples to write.
* \param buffer The pointer to the buffer containing the data.
*/
virtual void write(unsigned int length, sample_t* buffer)=0;
};
#endif //AUD_IWRITER

@ -0,0 +1,44 @@
/*
* $Id: AUD_JOSResampleFactory.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_JOSResampleFactory.cpp
* \ingroup audaspaceintern
*/
#include "AUD_JOSResampleFactory.h"
#include "AUD_JOSResampleReader.h"
AUD_JOSResampleFactory::AUD_JOSResampleFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
}
AUD_Reference<AUD_IReader> AUD_JOSResampleFactory::createReader()
{
return new AUD_JOSResampleReader(getReader(), m_specs.specs);
}

@ -0,0 +1,58 @@
/*
* $Id: AUD_JOSResampleFactory.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_JOSResampleFactory.h
* \ingroup audaspaceintern
*/
#ifndef AUD_JOSRESAMPLEFACTORY
#define AUD_JOSRESAMPLEFACTORY
#include "AUD_MixerFactory.h"
/**
* This factory creates a resampling reader that does Julius O. Smith's resampling algorithm.
*/
class AUD_JOSResampleFactory : public AUD_MixerFactory
{
private:
// hide copy constructor and operator=
AUD_JOSResampleFactory(const AUD_JOSResampleFactory&);
AUD_JOSResampleFactory& operator=(const AUD_JOSResampleFactory&);
public:
/**
* Creates a new factory.
* \param factory The input factory.
* \param specs The target specifications.
*/
AUD_JOSResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_JOSRESAMPLEFACTORY

@ -0,0 +1,420 @@
/*
* $Id: AUD_JOSResampleReader.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_JOSResampleReader.cpp
* \ingroup audaspaceintern
*/
#include "AUD_JOSResampleReader.h"
#include "AUD_JOSResampleReaderCoeff.cpp"
#include <cmath>
#include <cstring>
#include <iostream>
/* MSVC does not have lrint */
#ifdef _MSC_VER
#ifdef _M_X64
#include <emmintrin.h>
static inline int lrint(double d)
{
return _mm_cvtsd_si32(_mm_load_sd(&d));
}
#else
static inline int lrint(double d)
{
int i;
_asm{
fld d
fistp i
};
return i;
}
#endif
#endif
#define CC m_channels + channel
#define AUD_RATE_MAX 256
#define SHIFT_BITS 12
#define double_to_fp(x) (lrint(x * double(1 << SHIFT_BITS)))
#define int_to_fp(x) (x << SHIFT_BITS)
#define fp_to_int(x) (x >> SHIFT_BITS)
#define fp_to_double(x) (x * 1.0/(1 << SHIFT_BITS))
#define fp_rest(x) (x & ((1 << SHIFT_BITS) - 1))
#define fp_rest_to_double(x) fp_to_double(fp_rest(x))
AUD_JOSResampleReader::AUD_JOSResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs) :
AUD_ResampleReader(reader, specs.rate),
m_channels(AUD_CHANNELS_INVALID),
m_n(0),
m_P(0),
m_cache_valid(0),
m_last_factor(0)
{
}
void AUD_JOSResampleReader::reset()
{
m_cache_valid = 0;
m_n = 0;
m_P = 0;
m_last_factor = 0;
}
void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize)
{
unsigned int len;
double num_samples = double(m_len) / double(m_L);
// first calculate what length we need right now
if(factor >= 1)
len = ceil(num_samples);
else
len = (unsigned int)(ceil(num_samples / factor));
// then check if afterwards the length is enough for the maximum rate
if(len + size < num_samples * AUD_RATE_MAX)
len = num_samples * AUD_RATE_MAX - size;
if(m_n > len)
{
sample_t* buf = m_buffer.getBuffer();
len = m_n - len;
memmove(buf, buf + len * m_channels, (m_cache_valid - len) * samplesize);
m_n -= len;
m_cache_valid -= len;
}
m_buffer.assureSize((m_cache_valid + size) * samplesize, true);
}
#define RESAMPLE_METHOD(name, left, right) void AUD_JOSResampleReader::name(double target_factor, int length, sample_t* buffer)\
{\
sample_t* buf = m_buffer.getBuffer();\
\
int P, l, end, channel, i;\
double eta, v, f_increment, factor;\
\
m_sums.assureSize(m_channels * sizeof(double));\
double* sums = reinterpret_cast<double*>(m_sums.getBuffer());\
sample_t* data;\
const float* coeff = m_coeff;\
\
unsigned int P_increment;\
\
for(unsigned int t = 0; t < length; t++)\
{\
factor = (m_last_factor * (length - t - 1) + target_factor * (t + 1)) / length;\
\
memset(sums, 0, sizeof(double) * m_channels);\
\
if(factor >= 1)\
{\
P = double_to_fp(m_P * m_L);\
\
end = floor(m_len / double(m_L) - m_P) - 1;\
if(m_n < end)\
end = m_n;\
\
data = buf + (m_n - end) * m_channels;\
l = fp_to_int(P);\
eta = fp_rest_to_double(P);\
l += m_L * end;\
\
for(i = 0; i <= end; i++)\
{\
v = coeff[l] + eta * (coeff[l+1] - coeff[l]);\
l -= m_L;\
left\
}\
\
P = int_to_fp(m_L) - P;\
\
end = floor((m_len - 1) / double(m_L) + m_P) - 1;\
if(m_cache_valid - m_n - 2 < end)\
end = m_cache_valid - m_n - 2;\
\
data = buf + (m_n + 2 + end) * m_channels - 1;\
l = fp_to_int(P);\
eta = fp_rest_to_double(P);\
l += m_L * end;\
\
for(i = 0; i <= end; i++)\
{\
v = coeff[l] + eta * (coeff[l+1] - coeff[l]);\
l -= m_L;\
right\
}\
\
for(channel = 0; channel < m_channels; channel++)\
{\
*buffer = sums[channel];\
buffer++;\
}\
}\
else\
{\
f_increment = factor * m_L;\
P_increment = double_to_fp(f_increment);\
P = double_to_fp(m_P * f_increment);\
\
end = (int_to_fp(m_len) - P) / P_increment - 1;\
if(m_n < end)\
end = m_n;\
\
P += P_increment * end;\
data = buf + (m_n - end) * m_channels;\
l = fp_to_int(P);\
\
for(i = 0; i <= end; i++)\
{\
eta = fp_rest_to_double(P);\
v = coeff[l] + eta * (coeff[l+1] - coeff[l]);\
P -= P_increment;\
l = fp_to_int(P);\
left\
}\
\
P = -P;\
\
end = (int_to_fp(m_len) - P) / P_increment - 1;\
if(m_cache_valid - m_n - 2 < end)\
end = m_cache_valid - m_n - 2;\
\
P += P_increment * end;\
data = buf + (m_n + 2 + end) * m_channels - 1;\
l = fp_to_int(P);\
\
for(i = 0; i <= end; i++)\
{\
eta = fp_rest_to_double(P);\
v = coeff[l] + eta * (coeff[l+1] - coeff[l]);\
P -= P_increment;\
l = fp_to_int(P);\
right\
}\
\
for(channel = 0; channel < m_channels; channel++)\
{\
*buffer = f_increment / m_L * sums[channel];\
buffer++;\
}\
}\
\
m_P += fmod(1.0 / factor, 1.0);\
m_n += floor(1.0 / factor);\
\
if(m_P >= 1.0)\
{\
m_P -= 1.0;\
m_n++;\
}\
}\
}
RESAMPLE_METHOD(resample, {
channel = 0;
do
{
sums[channel] += *data * v;
channel++;
data++;
}
while(channel < m_channels);
}, {
channel = m_channels;
do
{
channel--;
sums[channel] += *data * v;
data--;
}
while(channel);
})
RESAMPLE_METHOD(resample_mono, {
*sums += *data * v;
data++;
}, {
*sums += *data * v;
data--;
})
RESAMPLE_METHOD(resample_stereo, {
sums[0] += data[0] * v;
sums[1] += data[1] * v;
data+=2;
}, {
data-=2;
sums[0] += data[1] * v;
sums[1] += data[2] * v;
})
void AUD_JOSResampleReader::seek(int position)
{
position = floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
m_reader->seek(position);
reset();
}
int AUD_JOSResampleReader::getLength() const
{
return floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
}
int AUD_JOSResampleReader::getPosition() const
{
return floor((m_reader->getPosition() + double(m_P))
* m_rate / m_reader->getSpecs().rate);
}
AUD_Specs AUD_JOSResampleReader::getSpecs() const
{
AUD_Specs specs = m_reader->getSpecs();
specs.rate = m_rate;
return specs;
}
void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
{
if(length == 0)
return;
AUD_Specs specs = m_reader->getSpecs();
int samplesize = AUD_SAMPLE_SIZE(specs);
double target_factor = double(m_rate) / double(specs.rate);
eos = false;
int len;
double num_samples = double(m_len) / double(m_L);
// check for channels changed
if(specs.channels != m_channels)
{
m_channels = specs.channels;
reset();
switch(m_channels)
{
case AUD_CHANNELS_MONO:
m_resample = &AUD_JOSResampleReader::resample_mono;
break;
case AUD_CHANNELS_STEREO:
m_resample = &AUD_JOSResampleReader::resample_stereo;
break;
default:
m_resample = &AUD_JOSResampleReader::resample;
break;
}
}
if(m_last_factor == 0)
m_last_factor = target_factor;
if(target_factor == 1 && m_last_factor == 1 && (m_P == 0))
{
// can read directly!
len = length - (m_cache_valid - m_n);
updateBuffer(len, target_factor, samplesize);
sample_t* buf = m_buffer.getBuffer();
m_reader->read(len, eos, buf + m_cache_valid * m_channels);
m_cache_valid += len;
length = m_cache_valid - m_n;
if(length > 0)
{
memcpy(buffer, buf + m_n * m_channels, length * samplesize);
m_n += length;
}
return;
}
// use minimum for the following calculations
double factor = AUD_MIN(target_factor, m_last_factor);
if(factor >= 1)
len = (m_n - m_cache_valid) + int(ceil(length / factor)) + ceil(num_samples);
else
len = (m_n - m_cache_valid) + int(ceil(length / factor) + ceil(num_samples / factor));
if(len > 0)
{
int should = len;
updateBuffer(len, factor, samplesize);
m_reader->read(len, eos, m_buffer.getBuffer() + m_cache_valid * m_channels);
m_cache_valid += len;
if(len < should)
{
if(len == 0 && eos)
length = 0;
else
{
// use maximum for the following calculations
factor = AUD_MAX(target_factor, m_last_factor);
if(eos)
{
// end of stream, let's check how many more samples we can produce
len = floor((m_cache_valid - m_n) * factor);
if(len < length)
length = len;
}
else
{
// not enough data available yet, so we recalculate how many samples we can calculate
if(factor >= 1)
len = floor((num_samples + m_cache_valid - m_n) * factor);
else
len = floor((num_samples * factor + m_cache_valid - m_n) * factor);
if(len < length)
length = len;
}
}
}
}
(this->*m_resample)(target_factor, length, buffer);
m_last_factor = target_factor;
if(m_n > m_cache_valid)
{
m_n = m_cache_valid;
}
eos = eos && ((m_n == m_cache_valid) || (length == 0));
}

@ -0,0 +1,137 @@
/*
* $Id: AUD_JOSResampleReader.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_JOSResampleReader.h
* \ingroup audaspaceintern
*/
#ifndef AUD_JOSRESAMPLEREADER
#define AUD_JOSRESAMPLEREADER
#include "AUD_ResampleReader.h"
#include "AUD_Buffer.h"
/**
* This resampling reader uses Julius O. Smith's resampling algorithm.
*/
class AUD_JOSResampleReader : public AUD_ResampleReader
{
private:
typedef void (AUD_JOSResampleReader::*AUD_resample_f)(double target_factor, int length, sample_t* buffer);
/**
* The half filter length.
*/
static const int m_len;
/**
* The sample step size for the filter.
*/
static const int m_L;
/**
* The filter coefficients.
*/
static const float m_coeff[];
/**
* The reader channels.
*/
AUD_Channels m_channels;
/**
* The sample position in the cache.
*/
unsigned int m_n;
/**
* The subsample position in the cache.
*/
double m_P;
/**
* The input data buffer.
*/
AUD_Buffer m_buffer;
/**
* Double buffer for the sums.
*/
AUD_Buffer m_sums;
/**
* How many samples in the cache are valid.
*/
int m_cache_valid;
/**
* Resample function.
*/
AUD_resample_f m_resample;
/**
* Last resampling factor.
*/
double m_last_factor;
// hide copy constructor and operator=
AUD_JOSResampleReader(const AUD_JOSResampleReader&);
AUD_JOSResampleReader& operator=(const AUD_JOSResampleReader&);
/**
* Resets the resampler to its initial state.
*/
void reset();
/**
* Updates the buffer to be as small as possible for the coming reading.
* \param size The size of samples to be read.
* \param factor The next resampling factor.
* \param samplesize The size of a sample.
*/
void updateBuffer(int size, double factor, int samplesize);
void resample(double target_factor, int length, sample_t* buffer);
void resample_mono(double target_factor, int length, sample_t* buffer);
void resample_stereo(double target_factor, int length, sample_t* buffer);
public:
/**
* Creates a resampling reader.
* \param reader The reader to mix.
* \param specs The target specification.
*/
AUD_JOSResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_JOSRESAMPLEREADER

File diff suppressed because it is too large Load Diff

@ -0,0 +1,33 @@
/*
* $Id: AUD_ReferenceHandler.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_Reference.cpp
* \ingroup audaspaceintern
*/
#include "AUD_Reference.h"
std::map<void*, unsigned int> AUD_ReferenceHandler::m_references;

@ -0,0 +1,47 @@
/*
* $Id: AUD_ResampleReader.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_ResampleReader.cpp
* \ingroup audaspaceintern
*/
#include "AUD_ResampleReader.h"
AUD_ResampleReader::AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate) :
AUD_EffectReader(reader), m_rate(rate)
{
}
void AUD_ResampleReader::setRate(AUD_SampleRate rate)
{
m_rate = rate;
}
AUD_SampleRate AUD_ResampleReader::getRate()
{
return m_rate;
}

@ -0,0 +1,68 @@
/*
* $Id: AUD_ResampleReader.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_ResampleReader.h
* \ingroup audaspaceintern
*/
#ifndef AUD_RESAMPLEREADER
#define AUD_RESAMPLEREADER
#include "AUD_EffectReader.h"
/**
* This is the base class for all resampling readers.
*/
class AUD_ResampleReader : public AUD_EffectReader
{
protected:
/**
* The target sampling rate.
*/
AUD_SampleRate m_rate;
/**
* Creates a resampling reader.
* \param reader The reader to mix.
* \param rate The target sampling rate.
*/
AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate);
public:
/**
* Sets the sample rate.
* \param rate The target sampling rate.
*/
virtual void setRate(AUD_SampleRate rate);
/**
* Retrieves the sample rate.
* \return The target sampling rate.
*/
virtual AUD_SampleRate getRate();
};
#endif // AUD_RESAMPLEREADER

@ -0,0 +1,344 @@
/*
* $Id: AUD_SequencerEntry.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_SequencerEntry.cpp
* \ingroup audaspaceintern
*/
#include "AUD_SequencerEntry.h"
#include "AUD_SequencerReader.h"
#include <cmath>
#include <limits>
AUD_SequencerEntry::AUD_SequencerEntry(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip, int id) :
m_status(0),
m_pos_status(1),
m_sound_status(0),
m_id(id),
m_sound(sound),
m_begin(begin),
m_end(end),
m_skip(skip),
m_muted(false),
m_relative(true),
m_volume_max(1.0f),
m_volume_min(0),
m_distance_max(std::numeric_limits<float>::max()),
m_distance_reference(1.0f),
m_attenuation(1.0f),
m_cone_angle_outer(360),
m_cone_angle_inner(360),
m_cone_volume_outer(0),
m_location(3),
m_orientation(4)
{
AUD_Quaternion q;
m_orientation.write(q.get());
float f = 1;
m_volume.write(&f);
m_pitch.write(&f);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&m_mutex, &attr);
pthread_mutexattr_destroy(&attr);
}
AUD_SequencerEntry::~AUD_SequencerEntry()
{
pthread_mutex_destroy(&m_mutex);
}
void AUD_SequencerEntry::lock()
{
pthread_mutex_lock(&m_mutex);
}
void AUD_SequencerEntry::unlock()
{
pthread_mutex_unlock(&m_mutex);
}
void AUD_SequencerEntry::setSound(AUD_Reference<AUD_IFactory> sound)
{
lock();
if(m_sound.get() != sound.get())
{
m_sound = sound;
m_sound_status++;
}
unlock();
}
void AUD_SequencerEntry::move(float begin, float end, float skip)
{
lock();
if(m_begin != begin || m_skip != skip || m_end != end)
{
m_begin = begin;
m_skip = skip;
m_end = end;
m_pos_status++;
}
unlock();
}
void AUD_SequencerEntry::mute(bool mute)
{
lock();
m_muted = mute;
unlock();
}
int AUD_SequencerEntry::getID() const
{
return m_id;
}
AUD_AnimateableProperty* AUD_SequencerEntry::getAnimProperty(AUD_AnimateablePropertyType type)
{
switch(type)
{
case AUD_AP_VOLUME:
return &m_volume;
case AUD_AP_PITCH:
return &m_pitch;
case AUD_AP_PANNING:
return &m_panning;
case AUD_AP_LOCATION:
return &m_location;
case AUD_AP_ORIENTATION:
return &m_orientation;
default:
return NULL;
}
}
void AUD_SequencerEntry::updateAll(float volume_max, float volume_min, float distance_max,
float distance_reference, float attenuation, float cone_angle_outer,
float cone_angle_inner, float cone_volume_outer)
{
lock();
if(volume_max != m_volume_max)
{
m_volume_max = volume_max;
m_status++;
}
if(volume_min != m_volume_min)
{
m_volume_min = volume_min;
m_status++;
}
if(distance_max != m_distance_max)
{
m_distance_max = distance_max;
m_status++;
}
if(distance_reference != m_distance_reference)
{
m_distance_reference = distance_reference;
m_status++;
}
if(attenuation != m_attenuation)
{
m_attenuation = attenuation;
m_status++;
}
if(cone_angle_outer != m_cone_angle_outer)
{
m_cone_angle_outer = cone_angle_outer;
m_status++;
}
if(cone_angle_inner != m_cone_angle_inner)
{
m_cone_angle_inner = cone_angle_inner;
m_status++;
}
if(cone_volume_outer != m_cone_volume_outer)
{
m_cone_volume_outer = cone_volume_outer;
m_status++;
}
unlock();
}
bool AUD_SequencerEntry::isRelative()
{
return m_relative;
}
void AUD_SequencerEntry::setRelative(bool relative)
{
lock();
if(m_relative != relative)
{
m_relative = relative;
m_status++;
}
unlock();
}
float AUD_SequencerEntry::getVolumeMaximum()
{
return m_volume_max;
}
void AUD_SequencerEntry::setVolumeMaximum(float volume)
{
lock();
m_volume_max = volume;
m_status++;
unlock();
}
float AUD_SequencerEntry::getVolumeMinimum()
{
return m_volume_min;
}
void AUD_SequencerEntry::setVolumeMinimum(float volume)
{
lock();
m_volume_min = volume;
m_status++;
unlock();
}
float AUD_SequencerEntry::getDistanceMaximum()
{
return m_distance_max;
}
void AUD_SequencerEntry::setDistanceMaximum(float distance)
{
lock();
m_distance_max = distance;
m_status++;
unlock();
}
float AUD_SequencerEntry::getDistanceReference()
{
return m_distance_reference;
}
void AUD_SequencerEntry::setDistanceReference(float distance)
{
lock();
m_distance_reference = distance;
m_status++;
unlock();
}
float AUD_SequencerEntry::getAttenuation()
{
return m_attenuation;
}
void AUD_SequencerEntry::setAttenuation(float factor)
{
lock();
m_attenuation = factor;
m_status++;
unlock();
}
float AUD_SequencerEntry::getConeAngleOuter()
{
return m_cone_angle_outer;
}
void AUD_SequencerEntry::setConeAngleOuter(float angle)
{
lock();
m_cone_angle_outer = angle;
m_status++;
unlock();
}
float AUD_SequencerEntry::getConeAngleInner()
{
return m_cone_angle_inner;
}
void AUD_SequencerEntry::setConeAngleInner(float angle)
{
lock();
m_cone_angle_inner = angle;
m_status++;
unlock();
}
float AUD_SequencerEntry::getConeVolumeOuter()
{
return m_cone_volume_outer;
}
void AUD_SequencerEntry::setConeVolumeOuter(float volume)
{
lock();
m_cone_volume_outer = volume;
m_status++;
unlock();
}

@ -0,0 +1,320 @@
/*
* $Id: AUD_SequencerEntry.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_SequencerEntry.h
* \ingroup audaspaceintern
*/
#ifndef AUD_SEQUENCERENTRY
#define AUD_SEQUENCERENTRY
#include "AUD_Reference.h"
#include "AUD_AnimateableProperty.h"
#include "AUD_IFactory.h"
#include <pthread.h>
/**
* This class represents a sequenced entry in a sequencer factory.
*/
class AUD_SequencerEntry
{
friend class AUD_SequencerHandle;
private:
/// The status of the entry. Changes every time a non-animated parameter changes.
int m_status;
/// The positional status of the entry. Changes every time the entry is moved.
int m_pos_status;
/// The sound status, changed when the sound is changed.
int m_sound_status;
/// The unique (regarding the factory) ID of the entry.
int m_id;
/// The sound this entry plays.
AUD_Reference<AUD_IFactory> m_sound;
/// The begin time.
float m_begin;
/// The end time.
float m_end;
/// How many seconds are skipped at the beginning.
float m_skip;
/// Whether the entry is muted.
bool m_muted;
/// Whether the position to the listener is relative or absolute
bool m_relative;
/// Maximum volume.
float m_volume_max;
/// Minimum volume.
float m_volume_min;
/// Maximum distance.
float m_distance_max;
/// Reference distance;
float m_distance_reference;
/// Attenuation
float m_attenuation;
/// Cone outer angle.
float m_cone_angle_outer;
/// Cone inner angle.
float m_cone_angle_inner;
/// Cone outer volume.
float m_cone_volume_outer;
/// The mutex for locking.
pthread_mutex_t m_mutex;
/// The animated volume.
AUD_AnimateableProperty m_volume;
/// The animated panning.
AUD_AnimateableProperty m_panning;
/// The animated pitch.
AUD_AnimateableProperty m_pitch;
/// The animated location.
AUD_AnimateableProperty m_location;
/// The animated orientation.
AUD_AnimateableProperty m_orientation;
public:
/**
* Creates a new sequenced entry.
* \param sound The sound this entry should play.
* \param begin The start time.
* \param end The end time or a negative value if determined by the sound.
* \param skip How much seconds should be skipped at the beginning.
* \param id The ID of the entry.
*/
AUD_SequencerEntry(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip, int id);
virtual ~AUD_SequencerEntry();
/**
* Locks the entry.
*/
void lock();
/**
* Unlocks the previously locked entry.
*/
void unlock();
/**
* Sets the sound of the entry.
* \param sound The new sound.
*/
void setSound(AUD_Reference<AUD_IFactory> sound);
/**
* Moves the entry.
* \param begin The new start time.
* \param end The new end time or a negative value if unknown.
* \param skip How many seconds to skip at the beginning.
*/
void move(float begin, float end, float skip);
/**
* Sets the muting state of the entry.
* \param mute Whether the entry should be muted or not.
*/
void mute(bool mute);
/**
* Retrieves the ID of the entry.
* \return The ID of the entry.
*/
int getID() const;
/**
* Retrieves one of the animated properties of the entry.
* \param type Which animated property to retrieve.
* \return A pointer to the animated property, valid as long as the
* entry is.
*/
AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
/**
* Updates all non-animated parameters of the entry.
* \param volume_max The maximum volume.
* \param volume_min The minimum volume.
* \param distance_max The maximum distance.
* \param distance_reference The reference distance.
* \param attenuation The attenuation.
* \param cone_angle_outer The outer cone opening angle.
* \param cone_angle_inner The inner cone opening angle.
* \param cone_volume_outer The volume outside the outer cone.
*/
void updateAll(float volume_max, float volume_min, float distance_max,
float distance_reference, float attenuation, float cone_angle_outer,
float cone_angle_inner, float cone_volume_outer);
/**
* Checks whether the source location, velocity and orientation are relative
* to the listener.
* \return Whether the source is relative.
*/
bool isRelative();
/**
* Sets whether the source location, velocity and orientation are relative
* to the listener.
* \param relative Whether the source is relative.
* \return Whether the action succeeded.
*/
void setRelative(bool relative);
/**
* Retrieves the maximum volume of a source.
* \return The maximum volume.
*/
float getVolumeMaximum();
/**
* Sets the maximum volume of a source.
* \param volume The new maximum volume.
* \return Whether the action succeeded.
*/
void setVolumeMaximum(float volume);
/**
* Retrieves the minimum volume of a source.
* \return The minimum volume.
*/
float getVolumeMinimum();
/**
* Sets the minimum volume of a source.
* \param volume The new minimum volume.
* \return Whether the action succeeded.
*/
void setVolumeMinimum(float volume);
/**
* Retrieves the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \return The maximum distance.
*/
float getDistanceMaximum();
/**
* Sets the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \param distance The new maximum distance.
* \return Whether the action succeeded.
*/
void setDistanceMaximum(float distance);
/**
* Retrieves the reference distance of a source.
* \return The reference distance.
*/
float getDistanceReference();
/**
* Sets the reference distance of a source.
* \param distance The new reference distance.
* \return Whether the action succeeded.
*/
void setDistanceReference(float distance);
/**
* Retrieves the attenuation of a source.
* \return The attenuation.
*/
float getAttenuation();
/**
* Sets the attenuation of a source.
* This value is used for distance calculation.
* \param factor The new attenuation.
* \return Whether the action succeeded.
*/
void setAttenuation(float factor);
/**
* Retrieves the outer angle of the cone of a source.
* \return The outer angle of the cone.
*/
float getConeAngleOuter();
/**
* Sets the outer angle of the cone of a source.
* \param angle The new outer angle of the cone.
* \return Whether the action succeeded.
*/
void setConeAngleOuter(float angle);
/**
* Retrieves the inner angle of the cone of a source.
* \return The inner angle of the cone.
*/
float getConeAngleInner();
/**
* Sets the inner angle of the cone of a source.
* \param angle The new inner angle of the cone.
* \return Whether the action succeeded.
*/
void setConeAngleInner(float angle);
/**
* Retrieves the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \return The outer volume of the cone.
*/
float getConeVolumeOuter();
/**
* Sets the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \param volume The new outer volume of the cone.
* \return Whether the action succeeded.
*/
void setConeVolumeOuter(float volume);
};
#endif //AUD_SEQUENCERENTRY

@ -0,0 +1,166 @@
/*
* $Id: AUD_SequencerHandle.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_SequencerHandle.cpp
* \ingroup audaspaceintern
*/
#include "AUD_SequencerHandle.h"
#include "AUD_ReadDevice.h"
AUD_SequencerHandle::AUD_SequencerHandle(AUD_Reference<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
m_entry(entry),
m_status(0),
m_pos_status(0),
m_sound_status(0),
m_device(device)
{
if(!entry->m_sound.isNull())
{
m_handle = device.play(entry->m_sound, true);
m_3dhandle = AUD_Reference<AUD_I3DHandle>(m_handle);
}
}
AUD_SequencerHandle::~AUD_SequencerHandle()
{
stop();
}
int AUD_SequencerHandle::compare(AUD_Reference<AUD_SequencerEntry> entry) const
{
if(m_entry->getID() < entry->getID())
return -1;
else if(m_entry->getID() == entry->getID())
return 0;
return 1;
}
void AUD_SequencerHandle::stop()
{
if(!m_handle.isNull())
m_handle->stop();
}
void AUD_SequencerHandle::update(float position, float frame)
{
if(!m_handle.isNull())
{
m_entry->lock();
if(position >= m_entry->m_end && m_entry->m_end >= 0)
m_handle->pause();
else if(position >= m_entry->m_begin)
m_handle->resume();
if(m_sound_status != m_entry->m_sound_status)
{
if(!m_handle.isNull())
m_handle->stop();
if(!m_entry->m_sound.isNull())
{
m_handle = m_device.play(m_entry->m_sound, true);
m_3dhandle = AUD_Reference<AUD_I3DHandle>(m_handle);
}
m_sound_status = m_entry->m_sound_status;
m_pos_status--;
m_status--;
}
if(m_pos_status != m_entry->m_pos_status)
{
seek(position);
m_pos_status = m_entry->m_pos_status;
}
if(m_status != m_entry->m_status)
{
m_3dhandle->setRelative(m_entry->m_relative);
m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
m_3dhandle->setDistanceMaximum(m_entry->m_distance_max);
m_3dhandle->setDistanceReference(m_entry->m_distance_reference);
m_3dhandle->setAttenuation(m_entry->m_attenuation);
m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
m_status = m_entry->m_status;
}
float value;
m_entry->m_volume.read(frame, &value);
m_handle->setVolume(value);
m_entry->m_pitch.read(frame, &value);
m_handle->setPitch(value);
m_entry->m_panning.read(frame, &value);
AUD_SoftwareDevice::setPanning(m_handle.get(), value);
AUD_Vector3 v, v2;
AUD_Quaternion q;
m_entry->m_orientation.read(frame, q.get());
m_3dhandle->setSourceOrientation(q);
m_entry->m_location.read(frame, v.get());
m_3dhandle->setSourceLocation(v);
m_entry->m_location.read(frame + 1, v2.get());
v2 -= v;
m_3dhandle->setSourceVelocity(v2);
if(m_entry->m_muted)
m_handle->setVolume(0);
m_entry->unlock();
}
}
void AUD_SequencerHandle::seek(float position)
{
if(!m_handle.isNull())
{
m_entry->lock();
if(position >= m_entry->m_end && m_entry->m_end >= 0)
{
m_handle->pause();
m_entry->unlock();
return;
}
float seekpos = position - m_entry->m_begin;
if(seekpos < 0)
seekpos = 0;
seekpos += m_entry->m_skip;
m_handle->seek(seekpos);
if(position < m_entry->m_begin)
m_handle->pause();
else
m_handle->resume();
m_entry->unlock();
}
}

@ -0,0 +1,107 @@
/*
* $Id: AUD_SequencerHandle.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_SequencerHandle.h
* \ingroup audaspaceintern
*/
#ifndef AUD_SEQUENCERHANDLE
#define AUD_SEQUENCERHANDLE
#include "AUD_SequencerEntry.h"
#include "AUD_IHandle.h"
#include "AUD_I3DHandle.h"
class AUD_ReadDevice;
/**
* Represents a playing sequenced entry.
*/
class AUD_SequencerHandle
{
private:
/// The entry this handle belongs to.
AUD_Reference<AUD_SequencerEntry> m_entry;
/// The handle in the read device.
AUD_Reference<AUD_IHandle> m_handle;
/// The 3D handle in the read device.
AUD_Reference<AUD_I3DHandle> m_3dhandle;
/// The last read status from the entry.
int m_status;
/// The last position status from the entry.
int m_pos_status;
/// The last sound status from the entry.
int m_sound_status;
/// The read device this handle is played on.
AUD_ReadDevice& m_device;
public:
/**
* Creates a new sequenced handle.
* \param entry The entry this handle plays.
* \param device The read device to play on.
*/
AUD_SequencerHandle(AUD_Reference<AUD_SequencerEntry> entry, AUD_ReadDevice& device);
/**
* Destroys the handle.
*/
~AUD_SequencerHandle();
/**
* Compares whether this handle is playing the same entry as supplied.
* \param entry The entry to compare to.
* \return Whether the entries ID is smaller, equal or bigger.
*/
int compare(AUD_Reference<AUD_SequencerEntry> entry) const;
/**
* Stops playing back the handle.
*/
void stop();
/**
* Updates the handle for playback.
* \param position The current time during playback.
* \param frame The current frame during playback.
*/
void update(float position, float frame);
/**
* Seeks the handle to a specific time position.
* \param position The time to seek to.
*/
void seek(float position);
};
#endif //AUD_SEQUENCERHANDLE

@ -0,0 +1,141 @@
/*
* $Id: AUD_SndFileWriter.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/sndfile/AUD_SndFileWriter.cpp
* \ingroup audsndfile
*/
#include "AUD_SndFileWriter.h"
#include <cstring>
static const char* fileopen_error = "AUD_SndFileWriter: File couldn't be written.";
static const char* format_error = "AUD_SndFileWriter: Unsupported format.";
AUD_SndFileWriter::AUD_SndFileWriter(std::string filename, AUD_DeviceSpecs specs,
AUD_Container format, AUD_Codec codec, unsigned int bitrate) :
m_specs(specs)
{
SF_INFO sfinfo;
sfinfo.channels = specs.channels;
sfinfo.samplerate = int(specs.rate);
switch(format)
{
case AUD_CONTAINER_FLAC:
sfinfo.format = SF_FORMAT_FLAC;
switch(specs.format)
{
case AUD_FORMAT_S16:
sfinfo.format |= SF_FORMAT_PCM_16;
break;
case AUD_FORMAT_S24:
sfinfo.format |= SF_FORMAT_PCM_24;
break;
case AUD_FORMAT_S32:
sfinfo.format |= SF_FORMAT_PCM_32;
break;
case AUD_FORMAT_FLOAT32:
sfinfo.format |= SF_FORMAT_FLOAT;
break;
case AUD_FORMAT_FLOAT64:
sfinfo.format |= SF_FORMAT_DOUBLE;
break;
default:
sfinfo.format = 0;
break;
}
break;
case AUD_CONTAINER_OGG:
if(codec == AUD_CODEC_VORBIS)
sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
else
sfinfo.format = 0;
break;
case AUD_CONTAINER_WAV:
sfinfo.format = SF_FORMAT_WAV;
switch(specs.format)
{
case AUD_FORMAT_U8:
sfinfo.format |= SF_FORMAT_PCM_U8;
break;
case AUD_FORMAT_S16:
sfinfo.format |= SF_FORMAT_PCM_16;
break;
case AUD_FORMAT_S24:
sfinfo.format |= SF_FORMAT_PCM_24;
break;
case AUD_FORMAT_S32:
sfinfo.format |= SF_FORMAT_PCM_32;
break;
case AUD_FORMAT_FLOAT32:
sfinfo.format |= SF_FORMAT_FLOAT;
break;
case AUD_FORMAT_FLOAT64:
sfinfo.format |= SF_FORMAT_DOUBLE;
break;
default:
sfinfo.format = 0;
break;
}
break;
default:
sfinfo.format = 0;
break;
}
if(sfinfo.format == 0)
AUD_THROW(AUD_ERROR_SPECS, format_error);
m_sndfile = sf_open(filename.c_str(), SFM_WRITE, &sfinfo);
if(!m_sndfile)
AUD_THROW(AUD_ERROR_FILE, fileopen_error);
}
AUD_SndFileWriter::~AUD_SndFileWriter()
{
sf_close(m_sndfile);
}
int AUD_SndFileWriter::getPosition() const
{
return m_position;
}
AUD_DeviceSpecs AUD_SndFileWriter::getSpecs() const
{
return m_specs;
}
void AUD_SndFileWriter::write(unsigned int length, sample_t* buffer)
{
length = sf_writef_float(m_sndfile, buffer, length);
m_position += length;
}

@ -0,0 +1,88 @@
/*
* $Id: AUD_SndFileWriter.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/sndfile/AUD_SndFileWriter.h
* \ingroup audsndfile
*/
#ifndef AUD_SNDFILEWRITER
#define AUD_SNDFILEWRITER
#include "AUD_IWriter.h"
#include <string>
#include <sndfile.h>
/**
* This class writes a sound file via libsndfile.
*/
class AUD_SndFileWriter : public AUD_IWriter
{
private:
/**
* The current position in samples.
*/
int m_position;
/**
* The specification of the audio data.
*/
AUD_DeviceSpecs m_specs;
/**
* The sndfile.
*/
SNDFILE* m_sndfile;
// hide copy constructor and operator=
AUD_SndFileWriter(const AUD_SndFileWriter&);
AUD_SndFileWriter& operator=(const AUD_SndFileWriter&);
public:
/**
* Creates a new writer.
* \param filename The path to the file to be read.
* \param specs The file's audio specification.
* \param format The file's container format.
* \param codec The codec used for encoding the audio data.
* \param bitrate The bitrate for encoding.
* \exception AUD_Exception Thrown if the file specified cannot be written
* with libsndfile.
*/
AUD_SndFileWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
/**
* Destroys the writer and closes the file.
*/
virtual ~AUD_SndFileWriter();
virtual int getPosition() const;
virtual AUD_DeviceSpecs getSpecs() const;
virtual void write(unsigned int length, sample_t* buffer);
};
#endif //AUD_SNDFILEWRITER

@ -0,0 +1,43 @@
/*
* $Id: BKE_speaker.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Jörg Müller.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef BKE_SPEAKER_H
#define BKE_SPEAKER_H
/** \file BKE_speaker.h
* \ingroup bke
* \brief General operations for speakers.
*/
void *add_speaker(const char *name);
struct Speaker *copy_speaker(struct Speaker *spk);
void make_local_speaker(struct Speaker *spk);
void free_speaker(struct Speaker *spk);
#endif

@ -0,0 +1,139 @@
/* speaker.c
*
*
* $Id: speaker.c 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Jörg Müller.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/speaker.c
* \ingroup bke
*/
#include "DNA_object_types.h"
#include "DNA_sound_types.h"
#include "DNA_speaker_types.h"
#include "BLI_math.h"
#include "BKE_animsys.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_speaker.h"
void *add_speaker(const char *name)
{
Speaker *spk;
spk= alloc_libblock(&G.main->speaker, ID_SPK, name);
spk->attenuation = 1.0f;
spk->cone_angle_inner = 360.0f;
spk->cone_angle_outer = 360.0f;
spk->cone_volume_outer = 1.0f;
spk->distance_max = FLT_MAX;
spk->distance_reference = 1.0f;
spk->flag = 0;
spk->pitch = 1.0f;
spk->sound = NULL;
spk->volume = 1.0f;
spk->volume_max = 1.0f;
spk->volume_min = 0.0f;
return spk;
}
Speaker *copy_speaker(Speaker *spk)
{
Speaker *spkn;
spkn= copy_libblock(spk);
if(spkn->sound)
spkn->sound->id.us++;
return spkn;
}
void make_local_speaker(Speaker *spk)
{
Main *bmain= G.main;
Object *ob;
int local=0, lib=0;
/* - only lib users: do nothing
* - only local users: set flag
* - mixed: make copy
*/
if(spk->id.lib==NULL) return;
if(spk->id.us==1) {
spk->id.lib= NULL;
spk->id.flag= LIB_LOCAL;
new_id(&bmain->speaker, (ID *)spk, NULL);
return;
}
ob= bmain->object.first;
while(ob) {
if(ob->data==spk) {
if(ob->id.lib) lib= 1;
else local= 1;
}
ob= ob->id.next;
}
if(local && lib==0) {
spk->id.lib= NULL;
spk->id.flag= LIB_LOCAL;
new_id(&bmain->speaker, (ID *)spk, NULL);
}
else if(local && lib) {
Speaker *spkn= copy_speaker(spk);
spkn->id.us= 0;
ob= bmain->object.first;
while(ob) {
if(ob->data==spk) {
if(ob->id.lib==NULL) {
ob->data= spkn;
spkn->id.us++;
spk->id.us--;
}
}
ob= ob->id.next;
}
}
}
void free_speaker(Speaker *spk)
{
if(spk->sound)
spk->sound->id.us--;
BKE_free_animdata((ID *)spk);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,163 @@
/*
* $Id: AnimationExporter.h 39809 2011-08-30 19:38:32Z gsrb3d $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
extern "C"
{
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
#include "DNA_lamp_types.h"
#include "DNA_camera_types.h"
#include "DNA_armature_types.h"
#include "DNA_material_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_fcurve.h"
#include "BKE_animsys.h"
#ifdef NAN_BUILDINFO
extern char build_rev[];
#endif
}
#include "MEM_guardedalloc.h"
#include "BKE_action.h" // pose functions
#include "BKE_armature.h"
#include "BKE_object.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
#include "RNA_access.h"
#include "COLLADASWSource.h"
#include "COLLADASWInstanceGeometry.h"
#include "COLLADASWInputList.h"
#include "COLLADASWPrimitves.h"
#include "COLLADASWVertices.h"
#include "COLLADASWLibraryAnimations.h"
#include "COLLADASWParamTemplate.h"
#include "COLLADASWParamBase.h"
#include "COLLADASWSampler.h"
#include "COLLADASWConstants.h"
#include "COLLADASWBaseInputElement.h"
#include "EffectExporter.h"
#include "collada_internal.h"
#include <vector>
#include <algorithm> // std::find
class AnimationExporter: COLLADASW::LibraryAnimations
{
private:
Scene *scene;
COLLADASW::StreamWriter *sw;
public:
AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) { this->sw = sw; }
void exportAnimations(Scene *sce);
// called for each exported object
void operator() (Object *ob);
protected:
void dae_animation(Object* ob, FCurve *fcu, char* transformName , bool is_param, Material *ma = NULL);
void write_bone_animation_matrix(Object *ob_arm, Bone *bone);
void write_bone_animation(Object *ob_arm, Bone *bone);
void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type);
bool is_bone_deform_group(Bone * bone);
void sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone);
void sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pChan);
void sample_animation(std::vector<float[4][4]> &mats, std::vector<float> &frames, Bone *bone, Object *ob_arm, bPoseChannel *pChan);
// dae_bone_animation -> add_bone_animation
// (blend this into dae_bone_animation)
void dae_bone_animation(std::vector<float> &fra, float *v, int tm_type, int axis, std::string ob_name, std::string bone_name);
void dae_baked_animation(std::vector<float> &fra, Object *ob_arm , Bone *bone);
float convert_time(float frame);
float convert_angle(float angle);
std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic);
void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis , bool transform);
void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length);
float * get_eul_source_for_quat(Object *ob );
std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name);
std::string create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name);
std::string create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name);
std::string create_xyz_source(float *v, int tot, const std::string& anim_id);
std::string create_4x4_source(std::vector<float> &frames , Object * ob_arm, Bone *bone , const std::string& anim_id);
std::string create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents);
std::string fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name);
// for rotation, axis name is always appended and the value of append_axis is ignored
std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
std::string get_light_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
std::string get_camera_param_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
void find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name);
void find_frames(Object *ob, std::vector<float> &fra);
void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode);
// enable fcurves driving a specific bone, disable all the rest
// if bone_name = NULL enable all fcurves
void enable_fcurves(bAction *act, char *bone_name);
bool hasAnimations(Scene *sce);
char* extract_transform_name(char *rna_path);
std::string getObjectBoneName ( Object *ob,const FCurve * fcu);
};

@ -0,0 +1,133 @@
/**
* $Id: IMB_indexer.h 39759 2011-08-28 21:48:52Z gsrb3d $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
* Contributor(s): Peter Schlaile
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef IMB_INDEXER_H
#define IMB_INDEXER_H
#ifdef WIN32
#include <io.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include "BKE_utildefines.h"
#include "IMB_anim.h"
/*
seperate animation index files to solve the following problems:
a) different timecodes within one file (like DTS/PTS, Timecode-Track,
"implicit" timecodes within DV-files and HDV-files etc.)
b) seeking difficulties within ffmpeg for files with timestamp holes
c) broken files that miss several frames / have varying framerates
d) use proxies accordingly
... we need index files, that provide us with
the binary(!) position, where we have to seek into the file *and*
the continuous frame number (ignoring the holes) starting from the
beginning of the file, so that we know, which proxy frame to serve.
This index has to be only built once for a file and is written into
the BL_proxy directory structure for later reuse in different blender files.
*/
typedef struct anim_index_entry {
int frameno;
unsigned long long seek_pos;
unsigned long long seek_pos_dts;
unsigned long long pts;
} anim_index_entry;
struct anim_index {
char name[256];
int num_entries;
struct anim_index_entry * entries;
};
struct anim_index_builder;
typedef struct anim_index_builder {
FILE * fp;
char name[FILE_MAXDIR + FILE_MAXFILE];
char temp_name[FILE_MAXDIR + FILE_MAXFILE];
void * private_data;
void (*delete_priv_data)(struct anim_index_builder * idx);
void (*proc_frame)(struct anim_index_builder * idx,
unsigned char * buffer,
int data_size,
struct anim_index_entry * entry);
} anim_index_builder;
anim_index_builder * IMB_index_builder_create(const char * name);
void IMB_index_builder_add_entry(anim_index_builder * fp,
int frameno, unsigned long long seek_pos,
unsigned long long seek_pos_dts,
unsigned long long pts);
void IMB_index_builder_proc_frame(anim_index_builder * fp,
unsigned char * buffer,
int data_size,
int frameno, unsigned long long seek_pos,
unsigned long long seek_pos_dts,
unsigned long long pts);
void IMB_index_builder_finish(anim_index_builder * fp, int rollback);
struct anim_index * IMB_indexer_open(const char * name);
unsigned long long IMB_indexer_get_seek_pos(
struct anim_index * idx, int frameno_index);
unsigned long long IMB_indexer_get_seek_pos_dts(
struct anim_index * idx, int frameno_index);
int IMB_indexer_get_frame_index(struct anim_index * idx, int frameno);
unsigned long long IMB_indexer_get_pts(struct anim_index * idx,
int frame_index);
int IMB_indexer_get_duration(struct anim_index * idx);
int IMB_indexer_can_scan(struct anim_index * idx,
int old_frame_index, int new_frame_index);
void IMB_indexer_close(struct anim_index * idx);
void IMB_free_indices(struct anim * anim);
int IMB_anim_index_get_frame_index(
struct anim * anim, IMB_Timecode_Type tc, int position);
struct anim * IMB_anim_open_proxy(
struct anim * anim, IMB_Proxy_Size preview_size);
struct anim_index * IMB_anim_open_index(
struct anim * anim, IMB_Timecode_Type tc);
int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size);
int IMB_timecode_to_array_index(IMB_Timecode_Type tc);
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,392 @@
/*
* $Id: indexer_dv.c 39833 2011-09-01 01:48:50Z campbellbarton $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Peter Schlaile <peter [at] schlaile [dot] de> 2011
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "IMB_indexer.h"
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include <time.h>
typedef struct indexer_dv_bitstream {
unsigned char* buffer;
int bit_pos;
} indexer_dv_bitstream;
static indexer_dv_bitstream bitstream_new(unsigned char* buffer_)
{
indexer_dv_bitstream rv;
rv.buffer = buffer_;
rv.bit_pos = 0;
return rv;
}
static unsigned long bitstream_get_bits(indexer_dv_bitstream * This, int num)
{
int byte_pos = This->bit_pos >> 3;
unsigned long i =
This->buffer[byte_pos] | (This->buffer[byte_pos + 1] << 8) |
(This->buffer[byte_pos + 2] << 16) |
(This->buffer[byte_pos + 3] << 24);
int rval = (i >> (This->bit_pos & 0x7)) & ((1 << num) - 1);
This->bit_pos += num;
return rval;
}
static int parse_num(indexer_dv_bitstream * b, int numbits) {
return bitstream_get_bits(b, numbits);
}
static int parse_bcd(indexer_dv_bitstream * b, int n)
{
char s[256];
char * p = s + (n+3)/4;
*p-- = 0;
while (n > 4) {
char a;
int v = bitstream_get_bits(b, 4);
n -= 4;
a = '0' + v;
if (a > '9') {
bitstream_get_bits(b, n);
return -1;
}
*p-- = a;
}
if (n) {
char a;
int v = bitstream_get_bits(b, n);
a = '0' + v;
if (a > '9') {
return -1;
}
*p-- = a;
}
return atol(s);
}
typedef struct indexer_dv_context
{
int rec_curr_frame;
int rec_curr_second;
int rec_curr_minute;
int rec_curr_hour;
int rec_curr_day;
int rec_curr_month;
int rec_curr_year;
char got_record_date;
char got_record_time;
time_t ref_time_read;
time_t ref_time_read_new;
int curr_frame;
time_t gap_start;
int gap_frame;
int frameno_offset;
anim_index_entry backbuffer[31];
int fsize;
anim_index_builder * idx;
} indexer_dv_context;
static void parse_packet(indexer_dv_context * This, unsigned char * p)
{
indexer_dv_bitstream b;
int type = p[0];
b = bitstream_new(p + 1);
switch (type) {
case 0x62: // Record date
parse_num(&b, 8);
This->rec_curr_day = parse_bcd(&b, 6);
parse_num(&b, 2);
This->rec_curr_month = parse_bcd(&b, 5);
parse_num(&b, 3);
This->rec_curr_year = parse_bcd(&b, 8);
if (This->rec_curr_year < 25) {
This->rec_curr_year += 2000;
} else {
This->rec_curr_year += 1900;
}
This->got_record_date = 1;
break;
case 0x63: // Record time
This->rec_curr_frame = parse_bcd(&b, 6);
parse_num(&b, 2);
This->rec_curr_second = parse_bcd(&b, 7);
parse_num(&b, 1);
This->rec_curr_minute = parse_bcd(&b, 7);
parse_num(&b, 1);
This->rec_curr_hour = parse_bcd(&b, 6);
This->got_record_time = 1;
break;
}
}
static void parse_header_block(indexer_dv_context * This, unsigned char* target)
{
int i;
for (i = 3; i < 80; i += 5) {
if (target[i] != 0xff) {
parse_packet(This, target + i);
}
}
}
static void parse_subcode_blocks(
indexer_dv_context * This, unsigned char* target)
{
int i,j;
for (j = 0; j < 2; j++) {
for (i = 3; i < 80; i += 5) {
if (target[i] != 0xff) {
parse_packet(This, target + i);
}
}
}
}
static void parse_vaux_blocks(
indexer_dv_context * This, unsigned char* target)
{
int i,j;
for (j = 0; j < 3; j++) {
for (i = 3; i < 80; i += 5) {
if (target[i] != 0xff) {
parse_packet(This, target + i);
}
}
target += 80;
}
}
static void parse_audio_headers(
indexer_dv_context * This, unsigned char* target)
{
int i;
for(i = 0; i < 9; i++) {
if (target[3] != 0xff) {
parse_packet(This, target + 3);
}
target += 16 * 80;
}
}
static void parse_frame(indexer_dv_context * This,
unsigned char * framebuffer, int isPAL)
{
int numDIFseq = isPAL ? 12 : 10;
unsigned char* target = framebuffer;
int ds;
for (ds = 0; ds < numDIFseq; ds++) {
parse_header_block(This, target);
target += 1 * 80;
parse_subcode_blocks(This, target);
target += 2 * 80;
parse_vaux_blocks(This, target);
target += 3 * 80;
parse_audio_headers(This, target);
target += 144 * 80;
}
}
static void inc_frame(int * frame, time_t * t, int isPAL)
{
if ((isPAL && *frame >= 25) || (!isPAL && *frame >= 30)) {
fprintf(stderr, "Ouchie: inc_frame: invalid_frameno: %d\n",
*frame);
}
(*frame)++;
if (isPAL && *frame >= 25) {
(*t)++;
*frame = 0;
} else if (!isPAL && *frame >= 30) {
(*t)++;
*frame = 0;
}
}
static void write_index(indexer_dv_context * This, anim_index_entry * entry)
{
IMB_index_builder_add_entry(
This->idx, entry->frameno + This->frameno_offset,
entry->seek_pos, entry->seek_pos_dts, entry->pts);
}
static void fill_gap(indexer_dv_context * This, int isPAL)
{
int i;
for (i = 0; i < This->fsize; i++) {
if (This->gap_start == This->ref_time_read &&
This->gap_frame == This->curr_frame) {
fprintf(stderr,
"indexer_dv::fill_gap: "
"can't seek backwards !\n");
break;
}
inc_frame(&This->gap_frame, &This->gap_start, isPAL);
}
while (This->gap_start != This->ref_time_read ||
This->gap_frame != This->curr_frame) {
inc_frame(&This->gap_frame, &This->gap_start, isPAL);
This->frameno_offset++;
}
for (i = 0; i < This->fsize; i++) {
write_index(This, This->backbuffer + i);
}
This->fsize = 0;
}
static void proc_frame(indexer_dv_context * This,
unsigned char* UNUSED(framebuffer), int isPAL)
{
struct tm recDate;
time_t t;
if (!This->got_record_date || !This->got_record_time) {
return;
}
recDate.tm_sec = This->rec_curr_second;
recDate.tm_min = This->rec_curr_minute;
recDate.tm_hour = This->rec_curr_hour;
recDate.tm_mday = This->rec_curr_day;
recDate.tm_mon = This->rec_curr_month - 1;
recDate.tm_year = This->rec_curr_year - 1900;
recDate.tm_wday = -1;
recDate.tm_yday = -1;
recDate.tm_isdst = -1;
t = mktime(&recDate);
if (t == -1) {
return;
}
This->ref_time_read_new = t;
if (This->ref_time_read < 0) {
This->ref_time_read = This->ref_time_read_new;
This->curr_frame = 0;
} else {
if (This->ref_time_read_new - This->ref_time_read == 1) {
This->curr_frame = 0;
This->ref_time_read = This->ref_time_read_new;
if (This->gap_frame >= 0) {
fill_gap(This, isPAL);
This->gap_frame = -1;
}
} else if (This->ref_time_read_new == This->ref_time_read) {
// do nothing
} else {
This->gap_start = This->ref_time_read;
This->gap_frame = This->curr_frame;
This->ref_time_read = This->ref_time_read_new;
This->curr_frame = -1;
}
}
}
static void indexer_dv_proc_frame(anim_index_builder * idx,
unsigned char * buffer,
int UNUSED(data_size),
struct anim_index_entry * entry)
{
int isPAL;
indexer_dv_context * This = (indexer_dv_context *) idx->private_data;
isPAL = (buffer[3] & 0x80);
This->got_record_date = FALSE;
This->got_record_time = FALSE;
parse_frame(This, buffer, isPAL);
proc_frame(This, buffer, isPAL);
if (This->curr_frame >= 0) {
write_index(This, entry);
inc_frame(&This->curr_frame, &This->ref_time_read, isPAL);
} else {
This->backbuffer[This->fsize++] = *entry;
if (This->fsize >= 31) {
int i;
fprintf(stderr, "indexer_dv::indexer_dv_proc_frame: "
"backbuffer overrun, emergency flush");
for (i = 0; i < This->fsize; i++) {
write_index(This, This->backbuffer+i);
}
This->fsize = 0;
}
}
}
static void indexer_dv_delete(anim_index_builder * idx)
{
int i = 0;
indexer_dv_context * This = (indexer_dv_context *) idx->private_data;
for (i = 0; i < This->fsize; i++) {
write_index(This, This->backbuffer+i);
}
MEM_freeN(This);
}
void IMB_indexer_dv_new(anim_index_builder * idx)
{
indexer_dv_context * rv = MEM_callocN(
sizeof(indexer_dv_context), "index_dv builder context");
rv->ref_time_read = -1;
rv->curr_frame = -1;
rv->gap_frame = -1;
rv->idx = idx;
idx->private_data = rv;
idx->proc_frame = indexer_dv_proc_frame;
idx->delete_priv_data = indexer_dv_delete;
}

@ -0,0 +1,69 @@
/*
* $Id: DNA_speaker_types.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Jörg Müller.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef DNA_SPEAKER_TYPES_H
#define DNA_SPEAKER_TYPES_H
/** \file DNA_speaker_types.h
* \ingroup DNA
*/
#include "DNA_ID.h"
struct AnimData;
struct bSound;
typedef struct Speaker {
ID id;
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
struct bSound *sound;
// not animatable properties
float volume_max;
float volume_min;
float distance_max;
float distance_reference;
float attenuation;
float cone_angle_outer;
float cone_angle_inner;
float cone_volume_outer;
// animatable properties
float volume;
float pitch;
// flag
short flag;
short pad1[3];
} Speaker;
/* **************** SPEAKER ********************* */
/* flag */
#define SPK_DS_EXPAND (1<<0)
#define SPK_MUTED (1<<1)
#define SPK_RELATIVE (1<<2)
#endif /* DNA_SPEAKER_TYPES_H */

@ -0,0 +1,172 @@
/*
* $Id: rna_speaker.c 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Jörg Müller.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/makesrna/intern/rna_speaker.c
* \ingroup RNA
*/
#include <stdlib.h>
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "rna_internal.h"
#include "DNA_speaker_types.h"
#include "DNA_sound_types.h"
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
#include "BKE_depsgraph.h"
#include "BKE_main.h"
#include "WM_api.h"
#include "WM_types.h"
#else
static void rna_def_speaker(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna= RNA_def_struct(brna, "Speaker", "ID");
RNA_def_struct_ui_text(srna, "Speaker", "Speaker datablock for 3D audio speaker objects");
RNA_def_struct_ui_icon(srna, ICON_SPEAKER);
prop= RNA_def_property(srna, "muted", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPK_MUTED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Mute", "Mutes the speaker.");
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
/* This shouldn't be changed actually, hiding it!
prop= RNA_def_property(srna, "relative", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SPK_RELATIVE);
RNA_def_property_ui_text(prop, "Relative", "Whether the source is relative to the camera or not.");
// RNA_def_property_update(prop, 0, "rna_Speaker_update");*/
prop= RNA_def_property(srna, "sound", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "sound");
RNA_def_property_struct_type(prop, "Sound");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Sound", "Sound datablock used by this speaker.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_sound_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "volume_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "volume_max");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Maximum Volume", "Maximum volume, no matter how near the object is.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_max_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "volume_min", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "volume_min");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Minimum Volume", "Minimum volume, no matter how far away the object is.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_min_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "distance_max", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "distance_max");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Maximum Distance", "Maximum distance for volume calculation, no matter how far away the object is.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_distance_max_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "distance_reference", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "distance_reference");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Reference Distance", "Reference distance at which volume is 100 %.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_distance_reference_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "attenuation", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "attenuation");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_text(prop, "Attenuation", "How strong the distance affects volume, depending on distance model.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_attenuation_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "cone_angle_outer", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cone_angle_outer");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 360.0f);
RNA_def_property_ui_text(prop, "Outer Cone Angle", "Outer angle of the cone in degrees, outside this cone the volume is the outer cone volume, between inner and outer cone the volume is interpolated.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_cone_angle_outer_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "cone_angle_inner", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cone_angle_inner");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 360.0f);
RNA_def_property_ui_text(prop, "Inner Cone Angle", "Inner angle of the cone in degrees, inside the cone the volume is 100 %.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_cone_angle_inner_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "cone_volume_outer", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cone_volume_outer");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Outer Cone Volume", "Volume outside the outer cone.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_cone_volume_outer_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "volume");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Volume", "How loud the sound is.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_volume_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
prop= RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "pitch");
RNA_def_property_range(prop, 0.1f, 10.0f);
RNA_def_property_ui_text(prop, "Pitch", "Playback pitch of the sound.");
// RNA_def_property_float_funcs(prop, NULL, "rna_Speaker_pitch_set", NULL);
// RNA_def_property_update(prop, 0, "rna_Speaker_update");
/* common */
rna_def_animdata_common(srna);
}
void RNA_def_speaker(BlenderRNA *brna)
{
rna_def_speaker(brna);
}
#endif

@ -0,0 +1,96 @@
/*
* $Id: rna_texture_api.c 39762 2011-08-28 23:44:43Z gsrb3d $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Tom Edwards
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/makesrna/intern/rna_texture_api.c
* \ingroup RNA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "RNA_define.h"
#include "BKE_utildefines.h"
#ifdef RNA_RUNTIME
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "DNA_scene_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "RE_pipeline.h"
void save_envmap(struct EnvMap *env, bContext *C, ReportList *reports, const char* filepath, struct Scene *scene, float layout[12])
{
if (scene == NULL) {
scene = CTX_data_scene(C);
}
RE_WriteEnvmapResult(reports, scene, env, filepath, scene->r.imtype, layout);
}
void clear_envmap(struct EnvMap *env, bContext *C)
{
Main *bmain = CTX_data_main(C);
Tex *tex;
BKE_free_envmapdata(env);
for (tex=bmain->tex.first; tex; tex=tex->id.next)
if (tex->env == env) {
WM_event_add_notifier(C, NC_TEXTURE|NA_EDITED, tex);
break;
}
}
#else
void RNA_api_environment_map(StructRNA *srna)
{
FunctionRNA *func;
PropertyRNA *parm;
static const float default_layout[] = { 0,0, 1,0, 2,0, 0,1, 1,1, 2,1 };
func= RNA_def_function(srna, "clear", "clear_envmap");
RNA_def_function_ui_description(func, "Discard the environment map and free it from memory.");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
func= RNA_def_function(srna,"save", "save_envmap");
RNA_def_function_ui_description(func, "Save the environment map to disc using the scene render settings.");
RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
parm= RNA_def_string_file_name(func,"filepath","",FILE_MAX,"File path","Location of the output file");
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken.");
parm = RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face. Order is [+Z -Z +Y -X -Y +X]. Use -1 to skip a face.", 0.0f, 0.0f);
}
#endif

@ -0,0 +1,453 @@
/**
* $Id: BL_Action.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Mitchell Stokes.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file BL_Action.cpp
* \ingroup ketsji
*/
#include <cstdlib>
#include "BL_Action.h"
#include "BL_ArmatureObject.h"
#include "BL_DeformableGameObject.h"
#include "BL_ShapeDeformer.h"
#include "KX_IpoConvert.h"
#include "KX_GameObject.h"
// These three are for getting the action from the logic manager
#include "KX_Scene.h"
#include "KX_PythonInit.h"
#include "SCA_LogicManager.h"
extern "C" {
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "RNA_access.h"
#include "RNA_define.h"
}
BL_Action::BL_Action(class KX_GameObject* gameobj)
:
m_action(NULL),
m_pose(NULL),
m_blendpose(NULL),
m_blendinpose(NULL),
m_ptrrna(NULL),
m_obj(gameobj),
m_startframe(0.f),
m_endframe(0.f),
m_endtime(0.f),
m_localtime(0.f),
m_blendin(0.f),
m_blendframe(0.f),
m_blendstart(0.f),
m_speed(0.f),
m_priority(0),
m_playmode(0),
m_ipo_flags(0),
m_done(true),
m_calc_localtime(true)
{
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
{
BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
m_ptrrna = new PointerRNA();
RNA_id_pointer_create(&obj->GetArmatureObject()->id, m_ptrrna);
}
else
{
BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
if (shape_deformer)
{
m_ptrrna = new PointerRNA();
RNA_id_pointer_create(&shape_deformer->GetKey()->id, m_ptrrna);
}
}
}
BL_Action::~BL_Action()
{
if (m_pose)
game_free_pose(m_pose);
if (m_blendpose)
game_free_pose(m_blendpose);
if (m_blendinpose)
game_free_pose(m_blendinpose);
if (m_ptrrna)
delete m_ptrrna;
ClearControllerList();
}
void BL_Action::ClearControllerList()
{
// Clear out the controller list
std::vector<SG_Controller*>::iterator it;
for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
{
m_obj->GetSGNode()->RemoveSGController((*it));
delete *it;
}
m_sg_contr_list.clear();
}
bool BL_Action::Play(const char* name,
float start,
float end,
short priority,
float blendin,
short play_mode,
float layer_weight,
short ipo_flags,
float playback_speed)
{
// Only start playing a new action if we're done, or if
// the new action has a higher priority
if (priority != 0 && !IsDone() && priority >= m_priority)
return false;
m_priority = priority;
bAction* prev_action = m_action;
// First try to load the action
m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name);
if (!m_action)
{
printf("Failed to load action: %s\n", name);
m_done = true;
return false;
}
if (prev_action != m_action)
{
// First get rid of any old controllers
ClearControllerList();
// Create an SG_Controller
SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
m_sg_contr_list.push_back(sg_contr);
m_obj->GetSGNode()->AddSGController(sg_contr);
sg_contr->SetObject(m_obj->GetSGNode());
// Extra controllers
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
{
sg_contr = BL_CreateLampIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
m_sg_contr_list.push_back(sg_contr);
m_obj->GetSGNode()->AddSGController(sg_contr);
sg_contr->SetObject(m_obj->GetSGNode());
}
else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
{
sg_contr = BL_CreateCameraIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
m_sg_contr_list.push_back(sg_contr);
m_obj->GetSGNode()->AddSGController(sg_contr);
sg_contr->SetObject(m_obj->GetSGNode());
}
}
m_ipo_flags = ipo_flags;
InitIPO();
// Setup blendin shapes/poses
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
{
BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
obj->GetMRDPose(&m_blendinpose);
}
else
{
BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
if (shape_deformer && shape_deformer->GetKey())
{
obj->GetShape(m_blendinshape);
// Now that we have the previous blend shape saved, we can clear out the key to avoid any
// further interference.
KeyBlock *kb;
for (kb=(KeyBlock*)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock*)kb->next)
kb->curval = 0.f;
}
}
// Now that we have an action, we have something we can play
m_starttime = KX_GetActiveEngine()->GetFrameTime();
m_startframe = m_localtime = start;
m_endframe = end;
m_blendin = blendin;
m_playmode = play_mode;
m_endtime = 0.f;
m_blendframe = 0.f;
m_blendstart = 0.f;
m_speed = playback_speed;
m_layer_weight = layer_weight;
m_done = false;
return true;
}
void BL_Action::Stop()
{
m_done = true;
}
bool BL_Action::IsDone()
{
return m_done;
}
void BL_Action::InitIPO()
{
// Initialize the IPOs
std::vector<SG_Controller*>::iterator it;
for (it = m_sg_contr_list.begin(); it != m_sg_contr_list.end(); it++)
{
(*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true);
(*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, m_ipo_flags & ACT_IPOFLAG_FORCE);
(*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, m_ipo_flags & ACT_IPOFLAG_ADD);
(*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, m_ipo_flags & ACT_IPOFLAG_LOCAL);
}
}
bAction *BL_Action::GetAction()
{
return (IsDone()) ? NULL : m_action;
}
float BL_Action::GetFrame()
{
return m_localtime;
}
void BL_Action::SetFrame(float frame)
{
// Clamp the frame to the start and end frame
if (frame < min(m_startframe, m_endframe))
frame = min(m_startframe, m_endframe);
else if (frame > max(m_startframe, m_endframe))
frame = max(m_startframe, m_endframe);
m_localtime = frame;
m_calc_localtime = false;
}
void BL_Action::SetPlayMode(short play_mode)
{
m_playmode = play_mode;
}
void BL_Action::SetTimes(float start, float end)
{
m_startframe = start;
m_endframe = end;
}
void BL_Action::SetLocalTime(float curtime)
{
float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
if (m_endframe < m_startframe)
dt = -dt;
m_localtime = m_startframe + dt;
}
void BL_Action::ResetStartTime(float curtime)
{
float dt = m_localtime - m_startframe;
m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
SetLocalTime(curtime);
}
void BL_Action::IncrementBlending(float curtime)
{
// Setup m_blendstart if we need to
if (m_blendstart == 0.f)
m_blendstart = curtime;
// Bump the blend frame
m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
// Clamp
if (m_blendframe>m_blendin)
m_blendframe = m_blendin;
}
void BL_Action::BlendShape(Key* key, float srcweight, std::vector<float>& blendshape)
{
vector<float>::const_iterator it;
float dstweight;
KeyBlock *kb;
dstweight = 1.0F - srcweight;
//printf("Dst: %f\tSrc: %f\n", srcweight, dstweight);
for (it=blendshape.begin(), kb = (KeyBlock*)key->block.first;
kb && it != blendshape.end();
kb = (KeyBlock*)kb->next, it++) {
//printf("OirgKeys: %f\t%f\n", kb->curval, (*it));
kb->curval = kb->curval * dstweight + (*it) * srcweight;
//printf("NewKey: %f\n", kb->curval);
}
//printf("\n");
}
void BL_Action::Update(float curtime)
{
// Don't bother if we're done with the animation
if (m_done)
return;
curtime -= KX_KetsjiEngine::GetSuspendedDelta();
if (m_calc_localtime)
SetLocalTime(curtime);
else
{
ResetStartTime(curtime);
m_calc_localtime = true;
}
// Handle wrap around
if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe))
{
switch(m_playmode)
{
case ACT_MODE_PLAY:
// Clamp
m_localtime = m_endframe;
m_done = true;
break;
case ACT_MODE_LOOP:
// Put the time back to the beginning
m_localtime = m_startframe;
m_starttime = curtime;
break;
case ACT_MODE_PING_PONG:
// Swap the start and end frames
float temp = m_startframe;
m_startframe = m_endframe;
m_endframe = temp;
m_starttime = curtime;
break;
}
if (!m_done)
InitIPO();
}
if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
{
BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
obj->GetPose(&m_pose);
// Extract the pose from the action
{
Object *arm = obj->GetArmatureObject();
bPose *temp = arm->pose;
arm->pose = m_pose;
animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime);
arm->pose = temp;
}
// Handle blending between armature actions
if (m_blendin && m_blendframe<m_blendin)
{
IncrementBlending(curtime);
// Calculate weight
float weight = 1.f - (m_blendframe/m_blendin);
// Blend the poses
game_blend_poses(m_pose, m_blendinpose, weight);
}
// Handle layer blending
if (m_layer_weight >= 0)
{
obj->GetMRDPose(&m_blendpose);
game_blend_poses(m_pose, m_blendpose, m_layer_weight);
}
obj->SetPose(m_pose);
obj->SetActiveAction(NULL, 0, curtime);
}
else
{
BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
// Handle shape actions if we have any
if (shape_deformer && shape_deformer->GetKey())
{
Key *key = shape_deformer->GetKey();
animsys_evaluate_action(m_ptrrna, m_action, NULL, m_localtime);
// Handle blending between shape actions
if (m_blendin && m_blendframe < m_blendin)
{
IncrementBlending(curtime);
float weight = 1.f - (m_blendframe/m_blendin);
// We go through and clear out the keyblocks so there isn't any interference
// from other shape actions
KeyBlock *kb;
for (kb=(KeyBlock*)key->block.first; kb; kb=(KeyBlock*)kb->next)
kb->curval = 0.f;
// Now blend the shape
BlendShape(key, weight, m_blendinshape);
}
// Handle layer blending
if (m_layer_weight >= 0)
{
obj->GetShape(m_blendshape);
BlendShape(key, m_layer_weight, m_blendshape);
}
obj->SetActiveAction(NULL, 0, curtime);
}
InitIPO();
m_obj->UpdateIPO(m_localtime, m_ipo_flags & ACT_IPOFLAG_CHILD);
}
}

@ -0,0 +1,144 @@
/**
* $Id: BL_Action.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Mitchell Stokes.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file BL_Action.h
* \ingroup ketsji
*/
#ifndef __BL_ACTION
#define __BL_ACTION
#include <vector>
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
class BL_Action
{
private:
struct bAction* m_action;
struct bPose* m_pose;
struct bPose* m_blendpose;
struct bPose* m_blendinpose;
struct PointerRNA *m_ptrrna;
std::vector<class SG_Controller*> m_sg_contr_list;
class KX_GameObject* m_obj;
std::vector<float> m_blendshape;
std::vector<float> m_blendinshape;
float m_startframe;
float m_endframe;
float m_starttime;
float m_endtime;
float m_localtime;
float m_blendin;
float m_blendframe;
float m_blendstart;
float m_layer_weight;
float m_speed;
short m_priority;
short m_playmode;
short m_ipo_flags;
bool m_done;
bool m_calc_localtime;
void ClearControllerList();
void InitIPO();
void SetLocalTime(float curtime);
void ResetStartTime(float curtime);
void IncrementBlending(float curtime);
void BlendShape(struct Key* key, float srcweight, std::vector<float>& blendshape);
public:
BL_Action(class KX_GameObject* gameobj);
~BL_Action();
/**
* Play an action
*/
bool Play(const char* name,
float start,
float end,
short priority,
float blendin,
short play_mode,
float layer_weight,
short ipo_flags,
float playback_speed);
/**
* Stop playing the action
*/
void Stop();
/**
* Whether or not the action is still playing
*/
bool IsDone();
/**
* Update the action's frame, etc.
*/
void Update(float curtime);
// Accessors
float GetFrame();
struct bAction *GetAction();
// Mutators
void SetFrame(float frame);
void SetPlayMode(short play_mode);
void SetTimes(float start, float end);
enum
{
ACT_MODE_PLAY = 0,
ACT_MODE_LOOP,
ACT_MODE_PING_PONG,
ACT_MODE_MAX,
};
enum
{
ACT_IPOFLAG_FORCE = 1,
ACT_IPOFLAG_LOCAL = 2,
ACT_IPOFLAG_ADD = 4,
ACT_IPOFLAG_CHILD = 8,
};
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_Action"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif //BL_ACTION

@ -0,0 +1,110 @@
/**
* $Id: BL_ActionManager.cpp 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Mitchell Stokes.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file BL_ActionManager.cpp
* \ingroup ketsji
*/
#include "BL_ActionManager.h"
BL_ActionManager::BL_ActionManager(class KX_GameObject *obj)
{
for (int i=0; i<MAX_ACTION_LAYERS; ++i)
m_layers[i] = new BL_Action(obj);
}
BL_ActionManager::~BL_ActionManager()
{
for (int i=0; i<MAX_ACTION_LAYERS; ++i)
delete m_layers[i];
}
float BL_ActionManager::GetActionFrame(short layer)
{
return m_layers[layer]->GetFrame();
return 0.f;
}
void BL_ActionManager::SetActionFrame(short layer, float frame)
{
m_layers[layer]->SetFrame(frame);
}
struct bAction *BL_ActionManager::GetCurrentAction(short layer)
{
return m_layers[layer]->GetAction();
return 0;
}
void BL_ActionManager::SetPlayMode(short layer, short mode)
{
m_layers[layer]->SetPlayMode(mode);
}
void BL_ActionManager::SetTimes(short layer, float start, float end)
{
m_layers[layer]->SetTimes(start, end);
}
bool BL_ActionManager::PlayAction(const char* name,
float start,
float end,
short layer,
short priority,
float blendin,
short play_mode,
float layer_weight,
short ipo_flags,
float playback_speed)
{
// Disable layer blending on the first layer
if (layer == 0) layer_weight = -1.f;
return m_layers[layer]->Play(name, start, end, priority, blendin, play_mode, layer_weight, ipo_flags, playback_speed);
}
void BL_ActionManager::StopAction(short layer)
{
m_layers[layer]->Stop();
}
bool BL_ActionManager::IsActionDone(short layer)
{
return m_layers[layer]->IsDone();
return true;
}
void BL_ActionManager::Update(float curtime)
{
for (int i=0; i<MAX_ACTION_LAYERS; ++i)
{
if (!m_layers[i]->IsDone())
{
m_layers[i]->Update(curtime);
}
}
}

@ -0,0 +1,106 @@
/**
* $Id: BL_ActionManager.h 39792 2011-08-30 09:15:55Z nexyon $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Mitchell Stokes.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file BL_ActionManager.cpp
* \ingroup ketsji
*/
#ifndef __BL_ACTIONMANAGER
#define __BL_ACTIONMANAGER
#include "BL_Action.h"
#define MAX_ACTION_LAYERS 8
/**
* BL_ActionManager is responsible for handling a KX_GameObject's actions.
*/
class BL_ActionManager
{
private:
BL_Action* m_layers[MAX_ACTION_LAYERS];
public:
BL_ActionManager(class KX_GameObject* obj);
~BL_ActionManager();
bool PlayAction(const char* name,
float start,
float end,
short layer=0,
short priority=0,
float blendin=0.f,
short play_mode=0,
float layer_weight=0.f,
short ipo_flags=0,
float playback_speed=1.f);
/**
* Gets the current frame of an action
*/
float GetActionFrame(short layer);
/**
* Sets the current frame of an action
*/
void SetActionFrame(short layer, float frame);
/**
* Gets the currently running action on the given layer
*/
struct bAction *GetCurrentAction(short layer);
/**
* Sets play mode of the action on the given layer
*/
void SetPlayMode(short layer, short mode);
/**
* Sets the start and end times of the action on the given layer
*/
void SetTimes(short layer, float start, float end);
/**
* Stop playing the action on the given layer
*/
void StopAction(short layer);
/**
* Check if an action has finished playing
*/
bool IsActionDone(short layer);
/**
* Update any running actions
*/
void Update(float);
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ActionManager"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif //BL_ACTIONMANAGER