00001 #include <algorithm>
00002 #include "audiere.h"
00003 #include "mixer.hpp"
00004 #include "output.hpp"
00005 #include "resampler.hpp"
00006
00007
00009
00010 Mixer::Mixer()
00011 {
00012 }
00013
00015
00016 Mixer::~Mixer()
00017 {
00018
00019 }
00020
00022
00023 void
00024 Mixer::GetFormat(int& channel_count, int& sample_rate, int& bits_per_sample)
00025 {
00026 channel_count = 2;
00027 sample_rate = 44100;
00028 bits_per_sample = 16;
00029 }
00030
00032
00033 int
00034 Mixer::Read(const int sample_count, void* samples)
00035 {
00036
00037 bool any_playing = false;
00038 SourceMap::iterator i = m_sources.begin();
00039 while (i != m_sources.end()) {
00040 any_playing |= i->second.is_playing;
00041 ++i;
00042 }
00043
00044
00045 if (!any_playing) {
00046 memset(samples, 0, 4 * sample_count);
00047 return sample_count;
00048 }
00049
00050 static const int BUFFER_SIZE = 4096;
00051
00052
00053 adr_s32 mix_buffer[BUFFER_SIZE];
00054 adr_s16 stream_buffer[BUFFER_SIZE * 2];
00055 std::fill(mix_buffer, mix_buffer + BUFFER_SIZE, 0);
00056
00057 adr_s16* out = (adr_s16*)samples;
00058 int left = sample_count;
00059 while (left > 0) {
00060 int playing = 0;
00061 int to_mix = std::min(BUFFER_SIZE, left);
00062
00063 SourceMap::iterator s = m_sources.begin();
00064 for (; s != m_sources.end(); ++s) {
00065 if (s->second.is_playing) {
00066 Read(s->first, s->second, to_mix, stream_buffer);
00067 for (int i = 0; i < to_mix * 2; ++i) {
00068 mix_buffer[i] += stream_buffer[i];
00069 }
00070 ++playing;
00071 }
00072 }
00073
00074
00075 if (playing != 0) {
00076 for (int i = 0; i < to_mix * 2; ++i) {
00077 *out++ = mix_buffer[i] / playing;
00078 }
00079 }
00080
00081 left -= to_mix;
00082 }
00083
00084 return sample_count;
00085 }
00086
00088
00089 bool
00090 Mixer::Reset()
00091 {
00092 return true;
00093 }
00094
00096
00097 void
00098 Mixer::AddSource(ISampleSource* source)
00099 {
00100
00101 SourceAttributes sa;
00102 sa.resampler = new Resampler(source);
00103 sa.last_l = 0;
00104 sa.last_r = 0;
00105 sa.is_playing = true;
00106 sa.volume = ADR_VOLUME_MAX;
00107
00108 m_sources[source] = sa;
00109 }
00110
00112
00113 void
00114 Mixer::RemoveSource(ISampleSource* source)
00115 {
00116 delete m_sources[source].resampler;
00117 m_sources.erase(source);
00118 }
00119
00121
00122 bool
00123 Mixer::IsPlaying(ISampleSource* source)
00124 {
00125 return m_sources[source].is_playing;
00126 }
00127
00129
00130 void
00131 Mixer::SetPlaying(ISampleSource* source, bool is_playing)
00132 {
00133 m_sources[source].is_playing = is_playing;
00134 }
00135
00137
00138 int
00139 Mixer::GetVolume(ISampleSource* source)
00140 {
00141 return m_sources[source].volume;
00142 }
00143
00145
00146 void
00147 Mixer::SetVolume(ISampleSource* source, int volume)
00148 {
00149 m_sources[source].volume = volume;
00150 }
00151
00153
00154 void
00155 Mixer::Read(ISampleSource* source,
00156 SourceAttributes& attr,
00157 int to_mix,
00158 adr_s16* buffer)
00159 {
00160 unsigned read = attr.resampler->Read(to_mix, buffer);
00161
00162 if (read == 0) {
00163 attr.is_playing = false;
00164 }
00165
00166
00167 adr_s16 l = attr.last_l;
00168 adr_s16 r = attr.last_r;
00169
00170 adr_s16* out = buffer;
00171 for (int i = 0; i < read; ++i) {
00172 *out = *out * attr.volume / 255;
00173 ++out;
00174 *out = *out * attr.volume / 255;
00175 ++out;
00176 }
00177
00178 if (read >= 0) {
00179 l = out[-2];
00180 r = out[-1];
00181 }
00182
00183 for (int i = read; i < to_mix; ++i) {
00184 *out++ = l;
00185 *out++ = r;
00186 }
00187
00188 attr.last_l = l;
00189 attr.last_r = r;
00190 }
00191