1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef AudioChannel_h
30#define AudioChannel_h
31
32#include "platform/PlatformExport.h"
33#include "platform/audio/AudioArray.h"
34#include "wtf/PassOwnPtr.h"
35
36namespace blink {
37
38// An AudioChannel represents a buffer of non-interleaved floating-point audio samples.
39// The PCM samples are normally assumed to be in a nominal range -1.0 -> +1.0
40class PLATFORM_EXPORT AudioChannel {
41    WTF_MAKE_NONCOPYABLE(AudioChannel);
42public:
43    // Memory can be externally referenced, or can be internally allocated with an AudioFloatArray.
44
45    // Reference an external buffer.
46    AudioChannel(float* storage, size_t length)
47        : m_length(length)
48        , m_rawPointer(storage)
49        , m_silent(false)
50    {
51    }
52
53    // Manage storage for us.
54    explicit AudioChannel(size_t length)
55        : m_length(length)
56        , m_rawPointer(0)
57        , m_silent(true)
58    {
59        m_memBuffer = adoptPtr(new AudioFloatArray(length));
60    }
61
62    // A "blank" audio channel -- must call set() before it's useful...
63    AudioChannel()
64        : m_length(0)
65        , m_rawPointer(0)
66        , m_silent(true)
67    {
68    }
69
70    // Redefine the memory for this channel.
71    // storage represents external memory not managed by this object.
72    void set(float* storage, size_t length)
73    {
74        m_memBuffer.clear(); // cleanup managed storage
75        m_rawPointer = storage;
76        m_length = length;
77        m_silent = false;
78    }
79
80    // How many sample-frames do we contain?
81    size_t length() const { return m_length; }
82
83    // resizeSmaller() can only be called with a new length <= the current length.
84    // The data stored in the bus will remain undisturbed.
85    void resizeSmaller(size_t newLength);
86
87    // Direct access to PCM sample data. Non-const accessor clears silent flag.
88    float* mutableData()
89    {
90        clearSilentFlag();
91        return m_rawPointer ? m_rawPointer : m_memBuffer->data();
92    }
93
94    const float* data() const { return m_rawPointer ? m_rawPointer : m_memBuffer->data(); }
95
96    // Zeroes out all sample values in buffer.
97    void zero()
98    {
99        if (m_silent)
100            return;
101
102        m_silent = true;
103
104        if (m_memBuffer.get())
105            m_memBuffer->zero();
106        else
107            memset(m_rawPointer, 0, sizeof(float) * m_length);
108    }
109
110    // Clears the silent flag.
111    void clearSilentFlag() { m_silent = false; }
112
113    bool isSilent() const { return m_silent; }
114
115    // Scales all samples by the same amount.
116    void scale(float scale);
117
118    // A simple memcpy() from the source channel
119    void copyFrom(const AudioChannel* sourceChannel);
120
121    // Copies the given range from the source channel.
122    void copyFromRange(const AudioChannel* sourceChannel, unsigned startFrame, unsigned endFrame);
123
124    // Sums (with unity gain) from the source channel.
125    void sumFrom(const AudioChannel* sourceChannel);
126
127    // Returns maximum absolute value (useful for normalization).
128    float maxAbsValue() const;
129
130private:
131    size_t m_length;
132
133    float* m_rawPointer;
134    OwnPtr<AudioFloatArray> m_memBuffer;
135    bool m_silent;
136};
137
138} // namespace blink
139
140#endif // AudioChannel_h
141