/*
* This file is part of AirReceiver.
*
* AirReceiver is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* AirReceiver is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with AirReceiver. If not, see <http://www.gnu.org/licenses/>.
*/
package org.dyndns.jkiddo.raop.server.audio;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
public final class SampleBuffer implements SampleIndexedAccessor
{
private final SampleDimensions m_bufferDimensions;
private final float[] m_buffer;
private final SampleIndexer m_samplesIndexer;
private double m_timeStamp;
public SampleBuffer(final float[] buffer, final SampleDimensions bufferDimensions, SampleIndexer samplesIndexer)
{
m_buffer = buffer;
m_bufferDimensions = bufferDimensions;
m_samplesIndexer = samplesIndexer;
}
public SampleBuffer(final float[] buffer, final SampleDimensions bufferDimensions, final SampleRange range, final SampleBufferLayout layout)
{
m_buffer = buffer;
m_bufferDimensions = bufferDimensions;
m_samplesIndexer = layout.getIndexer(bufferDimensions, range);
}
public SampleBuffer(final SampleDimensions dimensions)
{
this(new float[dimensions.getTotalSamples()], dimensions, new SampleRange(SampleOffset.Zero, dimensions), SampleBufferLayout.Banded);
}
public double getTimeStamp()
{
return m_timeStamp;
}
public void setTimeStamp(double timeStamp)
{
m_timeStamp = timeStamp;
}
@Override
public SampleBuffer slice(SampleRange range)
{
return new SampleBuffer(m_buffer, m_bufferDimensions, m_samplesIndexer.slice(range));
}
@Override
public SampleBuffer slice(SampleOffset offset, SampleDimensions dimensions)
{
return new SampleBuffer(m_buffer, m_bufferDimensions, m_samplesIndexer.slice(offset, dimensions));
}
public void copyFrom(final ByteBuffer src, final SampleDimensions srcDims, final SampleRange srcRange, final SampleByteBufferFormat srcByteFormat)
{
srcDims.assertContains(srcRange);
m_samplesIndexer.getDimensions().assertContains(srcRange.size);
final SampleIndexedAccessor srcAccessor = srcByteFormat.getAccessor(src, srcDims, srcRange);
for(int c = 0; c < srcRange.size.channels; ++c)
{
for(int s = 0; s < srcRange.size.samples; ++s)
{
m_buffer[m_samplesIndexer.getSampleIndex(c, s)] = srcAccessor.getSample(c, s);
}
}
}
public void copyFrom(final ByteBuffer src, final SampleDimensions srcDims, final SampleByteBufferFormat srcFormat)
{
copyFrom(src, srcDims, new SampleRange(srcDims), srcFormat);
}
public void copyFrom(final IntBuffer src, final SampleDimensions srcDims, final SampleRange srcRange, final SampleBufferLayout srcLayout, final Signedness srcSignedness)
{
m_samplesIndexer.getDimensions().assertContains(srcRange.size);
srcDims.assertContains(srcRange);
final SampleIndexer srcIndexer = srcLayout.getIndexer(srcDims, srcRange);
for(int c = 0; c < srcRange.size.channels; ++c)
{
for(int s = 0; s < srcRange.size.samples; ++s)
{
m_buffer[m_samplesIndexer.getSampleIndex(c, s)] = srcSignedness.shortToNormalizedFloat((short) src.get(srcIndexer.getSampleIndex(c, s)));
}
}
}
public void copyFrom(final IntBuffer src, final SampleDimensions srcDims, final SampleBufferLayout srcLayout, final Signedness srcSignedness)
{
copyFrom(src, srcDims, new SampleRange(srcDims), srcLayout, srcSignedness);
}
public void copyTo(final ByteBuffer dst, final SampleDimensions dstDims, final SampleOffset dstOffset, final SampleByteBufferFormat dstByteFormat)
{
dstDims.assertContains(new SampleRange(dstOffset, m_samplesIndexer.getDimensions()));
final SampleIndexedAccessor dstAccessor = dstByteFormat.getAccessor(dst, dstDims, dstOffset);
for(int c = 0; c < m_samplesIndexer.getDimensions().channels; ++c)
{
for(int s = 0; s < m_samplesIndexer.getDimensions().samples; ++s)
{
dstAccessor.setSample(c, s, m_buffer[m_samplesIndexer.getSampleIndex(c, s)]);
}
}
}
public void copyTo(final ByteBuffer dst, final SampleDimensions dstDims, final SampleByteBufferFormat dstFormat)
{
copyTo(dst, dstDims, SampleOffset.Zero, dstFormat);
}
@Override
public SampleDimensions getDimensions()
{
return m_samplesIndexer.getDimensions();
}
@Override
public float getSample(int channel, int sample)
{
return m_buffer[m_samplesIndexer.getSampleIndex(channel, sample)];
}
@Override
public void setSample(int channel, int sample, float value)
{
m_buffer[m_samplesIndexer.getSampleIndex(channel, sample)] = value;
}
}