Restore original mp3_audio_sink
Use the version written against the traditional audio streams.
This commit is contained in:
parent
03949b20e4
commit
d58b85b8ae
|
@ -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(); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue