1/*
2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.media.sound;
27
28import java.util.Arrays;
29
30import javax.sound.sampled.AudioFormat;
31
32/**
33 * This class is used to store audio buffer.
34 *
35 * @author Karl Helgason
36 */
37public final class SoftAudioBuffer {
38
39    private int size;
40    private float[] buffer;
41    private boolean empty = true;
42    private AudioFormat format;
43    private AudioFloatConverter converter;
44    private byte[] converter_buffer;
45
46    public SoftAudioBuffer(int size, AudioFormat format) {
47        this.size = size;
48        this.format = format;
49        converter = AudioFloatConverter.getConverter(format);
50    }
51
52    public void swap(SoftAudioBuffer swap)
53    {
54        int bak_size = size;
55        float[] bak_buffer = buffer;
56        boolean bak_empty = empty;
57        AudioFormat bak_format = format;
58        AudioFloatConverter bak_converter = converter;
59        byte[] bak_converter_buffer = converter_buffer;
60
61        size = swap.size;
62        buffer = swap.buffer;
63        empty = swap.empty;
64        format = swap.format;
65        converter = swap.converter;
66        converter_buffer = swap.converter_buffer;
67
68        swap.size = bak_size;
69        swap.buffer = bak_buffer;
70        swap.empty = bak_empty;
71        swap.format = bak_format;
72        swap.converter = bak_converter;
73        swap.converter_buffer = bak_converter_buffer;
74    }
75
76    public AudioFormat getFormat() {
77        return format;
78    }
79
80    public int getSize() {
81        return size;
82    }
83
84    public void clear() {
85        if (!empty) {
86            Arrays.fill(buffer, 0);
87            empty = true;
88        }
89    }
90
91    public boolean isSilent() {
92        return empty;
93    }
94
95    public float[] array() {
96        empty = false;
97        if (buffer == null)
98            buffer = new float[size];
99        return buffer;
100    }
101
102    public void get(byte[] buffer, int channel) {
103
104        int framesize_pc = (format.getFrameSize() / format.getChannels());
105        int c_len = size * framesize_pc;
106        if (converter_buffer == null || converter_buffer.length < c_len)
107            converter_buffer = new byte[c_len];
108
109        if (format.getChannels() == 1) {
110            converter.toByteArray(array(), size, buffer);
111        } else {
112            converter.toByteArray(array(), size, converter_buffer);
113            if (channel >= format.getChannels())
114                return;
115            int z_stepover = format.getChannels() * framesize_pc;
116            int k_stepover = framesize_pc;
117            for (int j = 0; j < framesize_pc; j++) {
118                int k = j;
119                int z = channel * framesize_pc + j;
120                for (int i = 0; i < size; i++) {
121                    buffer[z] = converter_buffer[k];
122                    z += z_stepover;
123                    k += k_stepover;
124                }
125            }
126        }
127    }
128}
129