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 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 "AudioArray.h"
33#include <memory>
34
35namespace WebCore {
36
37// An AudioChannel represents a buffer of non-interleaved floating-point audio samples.
38// The PCM samples are normally assumed to be in a nominal range -1.0 -> +1.0
39class AudioChannel {
40    WTF_MAKE_NONCOPYABLE(AudioChannel);
41public:
42    // Memory can be externally referenced, or can be internally allocated with an AudioFloatArray.
43
44    // Reference an external buffer.
45    explicit AudioChannel(float* storage, size_t length)
46        : m_length(length)
47        , m_rawPointer(storage)
48        , m_silent(false)
49    {
50    }
51
52    // Manage storage for us.
53    explicit AudioChannel(size_t length)
54        : m_length(length)
55        , m_rawPointer(0)
56        , m_silent(true)
57    {
58        m_memBuffer = std::make_unique<AudioFloatArray>(length);
59    }
60
61    // A "blank" audio channel -- must call set() before it's useful...
62    AudioChannel()
63        : m_length(0)
64        , m_rawPointer(0)
65        , m_silent(true)
66    {
67    }
68
69    // Redefine the memory for this channel.
70    // storage represents external memory not managed by this object.
71    void set(float* storage, size_t length)
72    {
73        m_memBuffer = nullptr; // cleanup managed storage
74        m_rawPointer = storage;
75        m_length = length;
76        m_silent = false;
77    }
78
79    // How many sample-frames do we contain?
80    size_t length() const { return m_length; }
81
82    // resizeSmaller() can only be called with a new length <= the current length.
83    // The data stored in the bus will remain undisturbed.
84    void resizeSmaller(size_t newLength);
85
86    // Direct access to PCM sample data. Non-const accessor clears silent flag.
87    float* mutableData()
88    {
89        clearSilentFlag();
90        return m_rawPointer ? m_rawPointer : m_memBuffer->data();
91    }
92
93    const float* data() const { return m_rawPointer ? m_rawPointer : m_memBuffer->data(); }
94
95    // Zeroes out all sample values in buffer.
96    void zero()
97    {
98        if (m_silent)
99            return;
100
101        m_silent = true;
102
103        if (m_memBuffer.get())
104            m_memBuffer->zero();
105        else
106            memset(m_rawPointer, 0, sizeof(float) * m_length);
107    }
108
109    // Clears the silent flag.
110    void clearSilentFlag() { m_silent = false; }
111
112    bool isSilent() const { return m_silent; }
113
114    // Scales all samples by the same amount.
115    void scale(float scale);
116
117    // A simple memcpy() from the source channel
118    void copyFrom(const AudioChannel* sourceChannel);
119
120    // Copies the given range from the source channel.
121    void copyFromRange(const AudioChannel* sourceChannel, unsigned startFrame, unsigned endFrame);
122
123    // Sums (with unity gain) from the source channel.
124    void sumFrom(const AudioChannel* sourceChannel);
125
126    // Returns maximum absolute value (useful for normalization).
127    float maxAbsValue() const;
128
129private:
130    size_t m_length;
131
132    float* m_rawPointer;
133    std::unique_ptr<AudioFloatArray> m_memBuffer;
134    bool m_silent;
135};
136
137} // WebCore
138
139#endif // AudioChannel_h
140