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