0e9833cd07f74f0c05491dc94dd8650ab2c3460e
[blender-staging.git] / intern / audaspace / FX / AUD_DelayReader.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * Copyright 2009-2011 Jörg Hermann Müller
5  *
6  * This file is part of AudaSpace.
7  *
8  * Audaspace is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * AudaSpace is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Audaspace; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file audaspace/FX/AUD_DelayReader.cpp
26  *  \ingroup audfx
27  */
28
29
30 #include "AUD_DelayReader.h"
31
32 #include <cstring>
33
34 AUD_DelayReader::AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay) :
35                 AUD_EffectReader(reader),
36                 m_delay(int((AUD_SampleRate)delay * reader->getSpecs().rate)),
37                 m_remdelay(int((AUD_SampleRate)delay * reader->getSpecs().rate))
38 {
39 }
40
41 void AUD_DelayReader::seek(int position)
42 {
43         if(position < m_delay)
44         {
45                 m_remdelay = m_delay - position;
46                 m_reader->seek(0);
47         }
48         else
49         {
50                 m_remdelay = 0;
51                 m_reader->seek(position - m_delay);
52         }
53 }
54
55 int AUD_DelayReader::getLength() const
56 {
57         int len = m_reader->getLength();
58         if(len < 0)
59                 return len;
60         return len + m_delay;
61 }
62
63 int AUD_DelayReader::getPosition() const
64 {
65         if(m_remdelay > 0)
66                 return m_delay - m_remdelay;
67         return m_reader->getPosition() + m_delay;
68 }
69
70 void AUD_DelayReader::read(int& length, bool& eos, sample_t* buffer)
71 {
72         if(m_remdelay > 0)
73         {
74                 AUD_Specs specs = m_reader->getSpecs();
75                 int samplesize = AUD_SAMPLE_SIZE(specs);
76
77                 if(length > m_remdelay)
78                 {
79                         memset(buffer, 0, m_remdelay * samplesize);
80
81                         int len = length - m_remdelay;
82                         m_reader->read(len, eos, buffer + m_remdelay * specs.channels);
83
84                         length = m_remdelay + len;
85
86                         m_remdelay = 0;
87                 }
88                 else
89                 {
90                         memset(buffer, 0, length * samplesize);
91                         m_remdelay -= length;
92                 }
93         }
94         else
95                 m_reader->read(length, eos, buffer);
96 }