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