Restore original mp3_audio_sink

Use the version written against the traditional audio streams.
This commit is contained in:
Ehmry - 2019-07-10 14:06:56 +02:00
parent 03949b20e4
commit d58b85b8ae
1 changed files with 50 additions and 15 deletions

View File

@ -14,6 +14,7 @@
/*
* TODO:
* - Metadata report
* - Configure the mpg123 volume control and equalizer
* - Optimize buffer sizes
*/
@ -21,7 +22,7 @@
#include <gems/magic_ring_buffer.h>
#include <os/static_root.h>
#include <libc/component.h>
#include <audio/source.h>
#include <audio_out_session/connection.h>
#include <terminal_session/connection.h>
#include <base/attached_rom_dataspace.h>
#include <base/attached_ram_dataspace.h>
@ -57,7 +58,7 @@ namespace Mp3_audio_sink {
}
struct Mp3_audio_sink::Decoder : Audio::Source
struct Mp3_audio_sink::Decoder
{
template <typename FUNC>
static void for_each_channel(FUNC const &func) {
@ -67,7 +68,9 @@ struct Mp3_audio_sink::Decoder : Audio::Source
Attached_rom_dataspace _config_rom { _env, "config" };
Audio::Stereo_out _stereo_out { _env, *this };
Audio_out::Connection _out_left { _env, "left", true, true };
Audio_out::Connection _out_right { _env, "right", false, false };
Audio_out::Connection *_out[NUM_CHANNELS];
void die_mpg123(mpg123_handle *mh, char const *msg)
{
@ -146,7 +149,7 @@ struct Mp3_audio_sink::Decoder : Audio::Source
return value;
}
bool fill(float *left, float *right, Genode::size_t samples) override;
void submit_audio();
/**
* Process client data, blocks until all data is consumed.
@ -170,7 +173,7 @@ struct Mp3_audio_sink::Decoder : Audio::Source
while (_pcm.write_avail() < samples) {
/* submit audio blocks for packet allocation */
_env.ep().wait_and_dispatch_one_io_signal();
submit_audio();
}
Genode::memcpy(_pcm.write_addr(), audio, bytes);
@ -184,6 +187,9 @@ struct Mp3_audio_sink::Decoder : Audio::Source
});
}
Io_signal_handler<Decoder> _progress_handler {
_env.ep(), *this, &Decoder::submit_audio };
Signal_handler<Decoder> _config_handler {
_env.ep(), *this, &Decoder::_handle_config };
@ -212,28 +218,57 @@ struct Mp3_audio_sink::Decoder : Audio::Source
Decoder(Genode::Env &env) : _env(env)
{
_out[LEFT] = &_out_left;
_out[RIGHT] = &_out_right;
_out_left.progress_sigh(_progress_handler);
_config_rom.sigh(_config_handler);
_handle_config();
}
};
bool Mp3_audio_sink::Decoder::fill(float *left,
float *right,
Genode::size_t samples)
void Mp3_audio_sink::Decoder::submit_audio()
{
using namespace Audio_out;
if (_pcm.read_avail() < samples*2) return false;
enum { STEREO_PERIOD = Audio_out::PERIOD*NUM_CHANNELS };
float const *buf = _pcm.read_addr();
for (unsigned i = 0; i < samples; ++i) {
left[i] = buf[(i<<1)|0];
right[i] = buf[(i<<1)|1];
if (_out_left.stream()->empty()) {
for_each_channel([&] (int const c) {
_out[c]->start(); });
log("Audio_out streams started");
}
_pcm.drain(samples*2);
return true;
while (_pcm.read_avail() > STEREO_PERIOD) {
Audio_out::Packet *p[NUM_CHANNELS];
while (true) {
try { p[LEFT] = _out[LEFT]->stream()->alloc(); break; }
catch (Audio_out::Stream::Alloc_failed) {
_out[LEFT]->wait_for_alloc(); }
}
unsigned const ppos = _out[LEFT]->stream()->packet_position(p[LEFT]);
p[RIGHT] = _out[RIGHT]->stream()->get(ppos);
float const *content = _pcm.read_addr();
/* copy channel contents into sessions */
for (unsigned i = 0; i < STEREO_PERIOD; i += NUM_CHANNELS) {
for_each_channel([&] (int const c) {
p[c]->content()[i/NUM_CHANNELS] = content[i+c]; });
}
for_each_channel([&] (int const c) {
_out[c]->submit(p[c]); });
_pcm.drain(STEREO_PERIOD);
}
if (_out_left.stream()->empty()) {
log("Audio_out queue underrun, stopping stream");
for_each_channel([&] (int const c) {
_out[c]->stop(); });
}
}