00001 #include "audiere.h"
00002 #include "internal.h"
00003 #include "utility.h"
00004
00005
00006 namespace audiere {
00007
00008 class BufferStream : public RefImplementation<SampleSource> {
00009 public:
00010 BufferStream(SampleBuffer* buffer) {
00011 m_buffer = buffer;
00012
00013
00014 int channel_count, sample_rate;
00015 SampleFormat sample_format;
00016 buffer->getFormat(channel_count, sample_rate, sample_format);
00017
00018 m_frame_size = channel_count * GetSampleSize(sample_format);
00019 m_frame_count = m_buffer->getLength();
00020 m_samples = (const u8*)m_buffer->getSamples();
00021
00022 m_position = 0;
00023 }
00024
00025
00026 void ADR_CALL getFormat(
00027 int& channel_count,
00028 int& sample_rate,
00029 SampleFormat& sample_format)
00030 {
00031 m_buffer->getFormat(channel_count, sample_rate, sample_format);
00032 }
00033
00034
00035 int ADR_CALL read(int frame_count, void* buffer) {
00036 int to_read = std::min(frame_count, m_frame_count - m_position);
00037 memcpy(
00038 buffer,
00039 m_samples + m_position * m_frame_size,
00040 to_read * m_frame_size);
00041 m_position += to_read;
00042 return to_read;
00043 }
00044
00045
00046 void ADR_CALL reset() {
00047 m_position = 0;
00048 }
00049
00050
00051 bool ADR_CALL isSeekable() { return true; }
00052 int ADR_CALL getLength() { return m_frame_count; }
00053 void ADR_CALL setPosition(int position) { m_position = position; }
00054 int ADR_CALL getPosition() { return m_position; }
00055
00056 private:
00057 RefPtr<SampleBuffer> m_buffer;
00058 int m_frame_size;
00059 int m_frame_count;
00060 const u8* m_samples;
00061
00062 int m_position;
00063 };
00064
00065
00066 class SampleBufferImpl : public RefImplementation<SampleBuffer> {
00067 public:
00068 SampleBufferImpl(
00069 void* samples, int frame_count,
00070 int channel_count, int sample_rate, SampleFormat sample_format)
00071 {
00072 const int frame_size = channel_count * GetSampleSize(sample_format);
00073 const int buffer_size = frame_count * frame_size;
00074 m_samples = new u8[buffer_size];
00075 if (samples) {
00076 memcpy(m_samples, samples, buffer_size);
00077 } else {
00078 memset(m_samples, 0, buffer_size);
00079 }
00080
00081 m_frame_count = frame_count;
00082 m_channel_count = channel_count;
00083 m_sample_rate = sample_rate;
00084 m_sample_format = sample_format;
00085 }
00086
00087 ~SampleBufferImpl() {
00088 delete[] m_samples;
00089 }
00090
00091 void ADR_CALL getFormat(
00092 int& channel_count,
00093 int& sample_rate,
00094 SampleFormat& sample_format)
00095 {
00096 channel_count = m_channel_count;
00097 sample_rate = m_sample_rate;
00098 sample_format = m_sample_format;
00099 }
00100
00101 int ADR_CALL getLength() {
00102 return m_frame_count;
00103 }
00104
00105 const void* ADR_CALL getSamples() {
00106 return m_samples;
00107 }
00108
00109 SampleSource* ADR_CALL openStream() {
00110 return new BufferStream(this);
00111 }
00112
00113 private:
00114 u8* m_samples;
00115 int m_frame_count;
00116 int m_channel_count;
00117 int m_sample_rate;
00118 SampleFormat m_sample_format;
00119 };
00120
00121
00122 ADR_EXPORT(SampleBuffer*, AdrCreateSampleBuffer)(
00123 void* samples,
00124 int frame_count,
00125 int channel_count,
00126 int sample_rate,
00127 SampleFormat sample_format)
00128 {
00129 return new SampleBufferImpl(
00130 samples, frame_count,
00131 channel_count, sample_rate, sample_format);
00132 }
00133
00134 ADR_EXPORT(SampleBuffer*, AdrCreateSampleBufferFromSource)(
00135 SampleSource* source)
00136 {
00137
00138
00139 if (!source || !source->isSeekable()) {
00140 return 0;
00141 }
00142
00143 int length = source->getLength();
00144 int channel_count, sample_rate;
00145 SampleFormat sample_format;
00146 source->getFormat(channel_count, sample_rate, sample_format);
00147
00148 int stream_length_bytes = length *
00149 channel_count * GetSampleSize(sample_format);
00150 u8* buffer = new u8[stream_length_bytes];
00151
00152 source->setPosition(0);
00153 source->read(length, buffer);
00154
00155 SampleBuffer* sb = CreateSampleBuffer(
00156 buffer, length, channel_count, sample_rate, sample_format);
00157
00158 delete[] buffer;
00159 return sb;
00160 }
00161
00162 }