forked from bartvdbraak/blender
add missing files after merging
This commit is contained in:
parent
d31d7fd487
commit
034cda72d3
42
intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
Executable file
42
intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
Executable file
@ -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);
|
||||
}
|
65
intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
Executable file
65
intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
Executable file
@ -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
|
45
intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
Executable file
45
intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
Executable file
@ -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);
|
||||
}
|
56
intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
Executable file
56
intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
Executable file
@ -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
|
305
intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
Executable file
305
intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
Executable file
@ -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;
|
||||
}
|
||||
}
|
140
intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
Executable file
140
intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
Executable file
@ -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
|
159
intern/audaspace/intern/AUD_AnimateableProperty.cpp
Executable file
159
intern/audaspace/intern/AUD_AnimateableProperty.cpp
Executable file
@ -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;
|
||||
}
|
108
intern/audaspace/intern/AUD_AnimateableProperty.h
Executable file
108
intern/audaspace/intern/AUD_AnimateableProperty.h
Executable file
@ -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
|
97
intern/audaspace/intern/AUD_FileWriter.cpp
Executable file
97
intern/audaspace/intern/AUD_FileWriter.cpp
Executable file
@ -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);
|
||||
}
|
||||
}
|
75
intern/audaspace/intern/AUD_FileWriter.h
Executable file
75
intern/audaspace/intern/AUD_FileWriter.h
Executable file
@ -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
|
218
intern/audaspace/intern/AUD_I3DHandle.h
Executable file
218
intern/audaspace/intern/AUD_I3DHandle.h
Executable file
@ -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
|
181
intern/audaspace/intern/AUD_IHandle.h
Executable file
181
intern/audaspace/intern/AUD_IHandle.h
Executable file
@ -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
|
69
intern/audaspace/intern/AUD_IWriter.h
Executable file
69
intern/audaspace/intern/AUD_IWriter.h
Executable file
@ -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
|
44
intern/audaspace/intern/AUD_JOSResampleFactory.cpp
Executable file
44
intern/audaspace/intern/AUD_JOSResampleFactory.cpp
Executable file
@ -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);
|
||||
}
|
58
intern/audaspace/intern/AUD_JOSResampleFactory.h
Executable file
58
intern/audaspace/intern/AUD_JOSResampleFactory.h
Executable file
@ -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
|
420
intern/audaspace/intern/AUD_JOSResampleReader.cpp
Executable file
420
intern/audaspace/intern/AUD_JOSResampleReader.cpp
Executable file
@ -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));
|
||||
}
|
137
intern/audaspace/intern/AUD_JOSResampleReader.h
Executable file
137
intern/audaspace/intern/AUD_JOSResampleReader.h
Executable file
@ -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
|
32547
intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
Executable file
32547
intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
Executable file
File diff suppressed because it is too large
Load Diff
33
intern/audaspace/intern/AUD_ReferenceHandler.cpp
Executable file
33
intern/audaspace/intern/AUD_ReferenceHandler.cpp
Executable file
@ -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;
|
47
intern/audaspace/intern/AUD_ResampleReader.cpp
Executable file
47
intern/audaspace/intern/AUD_ResampleReader.cpp
Executable file
@ -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;
|
||||
}
|
68
intern/audaspace/intern/AUD_ResampleReader.h
Executable file
68
intern/audaspace/intern/AUD_ResampleReader.h
Executable file
@ -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
|
344
intern/audaspace/intern/AUD_SequencerEntry.cpp
Executable file
344
intern/audaspace/intern/AUD_SequencerEntry.cpp
Executable file
@ -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();
|
||||
}
|
320
intern/audaspace/intern/AUD_SequencerEntry.h
Executable file
320
intern/audaspace/intern/AUD_SequencerEntry.h
Executable file
@ -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
|
166
intern/audaspace/intern/AUD_SequencerHandle.cpp
Executable file
166
intern/audaspace/intern/AUD_SequencerHandle.cpp
Executable file
@ -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();
|
||||
}
|
||||
}
|
107
intern/audaspace/intern/AUD_SequencerHandle.h
Executable file
107
intern/audaspace/intern/AUD_SequencerHandle.h
Executable file
@ -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
|
141
intern/audaspace/sndfile/AUD_SndFileWriter.cpp
Executable file
141
intern/audaspace/sndfile/AUD_SndFileWriter.cpp
Executable file
@ -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;
|
||||
}
|
88
intern/audaspace/sndfile/AUD_SndFileWriter.h
Executable file
88
intern/audaspace/sndfile/AUD_SndFileWriter.h
Executable file
@ -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
|
43
source/blender/blenkernel/BKE_speaker.h
Executable file
43
source/blender/blenkernel/BKE_speaker.h
Executable file
@ -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
|
139
source/blender/blenkernel/intern/speaker.c
Executable file
139
source/blender/blenkernel/intern/speaker.c
Executable file
@ -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);
|
||||
}
|
1300
source/blender/collada/AnimationExporter.cpp
Executable file
1300
source/blender/collada/AnimationExporter.cpp
Executable file
File diff suppressed because it is too large
Load Diff
163
source/blender/collada/AnimationExporter.h
Executable file
163
source/blender/collada/AnimationExporter.h
Executable file
@ -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);
|
||||
};
|
133
source/blender/imbuf/intern/IMB_indexer.h
Executable file
133
source/blender/imbuf/intern/IMB_indexer.h
Executable file
@ -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
|
1142
source/blender/imbuf/intern/indexer.c
Executable file
1142
source/blender/imbuf/intern/indexer.c
Executable file
File diff suppressed because it is too large
Load Diff
392
source/blender/imbuf/intern/indexer_dv.c
Executable file
392
source/blender/imbuf/intern/indexer_dv.c
Executable file
@ -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;
|
||||
}
|
69
source/blender/makesdna/DNA_speaker_types.h
Executable file
69
source/blender/makesdna/DNA_speaker_types.h
Executable file
@ -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 */
|
||||
|
172
source/blender/makesrna/intern/rna_speaker.c
Executable file
172
source/blender/makesrna/intern/rna_speaker.c
Executable file
@ -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
|
||||
|
96
source/blender/makesrna/intern/rna_texture_api.c
Executable file
96
source/blender/makesrna/intern/rna_texture_api.c
Executable file
@ -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
|
453
source/gameengine/Ketsji/BL_Action.cpp
Executable file
453
source/gameengine/Ketsji/BL_Action.cpp
Executable file
@ -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);
|
||||
}
|
||||
}
|
144
source/gameengine/Ketsji/BL_Action.h
Executable file
144
source/gameengine/Ketsji/BL_Action.h
Executable file
@ -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
|
||||
|
110
source/gameengine/Ketsji/BL_ActionManager.cpp
Executable file
110
source/gameengine/Ketsji/BL_ActionManager.cpp
Executable file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
106
source/gameengine/Ketsji/BL_ActionManager.h
Executable file
106
source/gameengine/Ketsji/BL_ActionManager.h
Executable file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user