use Attached_dataspace at audio streams

Ref #1987
This commit is contained in:
Emery Hemingway 2017-01-06 15:32:53 +01:00 committed by Norman Feske
parent 1f019d65d3
commit f957fcdd98
11 changed files with 107 additions and 138 deletions

View File

@ -51,9 +51,9 @@ class Audio_out::Session_component : public Audio_out::Session_rpc_object
public:
Session_component(Channel_number channel, Signal_context_capability cap)
Session_component(Genode::Env &env, Channel_number channel, Signal_context_capability cap)
:
Session_rpc_object(cap), _channel(channel)
Session_rpc_object(env, cap), _channel(channel)
{
Audio_out::channel_acquired[_channel] = this;
}
@ -69,7 +69,7 @@ class Audio_out::Out
{
private:
Genode::Entrypoint &_ep;
Genode::Env &_env;
Genode::Signal_handler<Audio_out::Out> _data_avail_dispatcher;
Genode::Signal_handler<Audio_out::Out> _notify_dispatcher;
@ -173,11 +173,11 @@ class Audio_out::Out
public:
Out(Genode::Entrypoint &ep)
Out(Genode::Env &env)
:
_ep(ep),
_data_avail_dispatcher(ep, *this, &Audio_out::Out::_handle_data_avail),
_notify_dispatcher(ep, *this, &Audio_out::Out::_handle_notify)
_env(env),
_data_avail_dispatcher(env.ep(), *this, &Audio_out::Out::_handle_data_avail),
_notify_dispatcher(env.ep(), *this, &Audio_out::Out::_handle_notify)
{
/* play a silence packet to get the driver running */
_play_silence();
@ -262,7 +262,7 @@ class Audio_out::Root : public Audio_out::Root_component
{
private:
Genode::Entrypoint &_ep;
Genode::Env &_env;
Signal_context_capability _cap;
@ -278,16 +278,16 @@ class Audio_out::Root : public Audio_out::Root_component
Out::channel_number(channel_name, &channel_number);
return new (md_alloc())
Session_component(channel_number, _cap);
Session_component(_env, channel_number, _cap);
}
public:
Root(Genode::Entrypoint &ep, Allocator &md_alloc,
Root(Genode::Env &env, Allocator &md_alloc,
Signal_context_capability cap)
:
Root_component(&ep.rpc_ep(), &md_alloc),
_ep(ep), _cap(cap)
Root_component(env.ep(), md_alloc),
_env(env), _cap(cap)
{ }
};
@ -315,9 +315,9 @@ class Audio_in::Session_component : public Audio_in::Session_rpc_object
public:
Session_component(Channel_number channel,
Session_component(Genode::Env &env, Channel_number channel,
Genode::Signal_context_capability cap)
: Session_rpc_object(cap), _channel(channel) {
: Session_rpc_object(env, cap), _channel(channel) {
channel_acquired = this; }
~Session_component() { channel_acquired = nullptr; }
@ -328,7 +328,7 @@ class Audio_in::In
{
private:
Genode::Entrypoint &_ep;
Genode::Env &_env;
Genode::Signal_handler<Audio_in::In> _notify_dispatcher;
bool _active() { return channel_acquired && channel_acquired->active(); }
@ -375,10 +375,10 @@ class Audio_in::In
public:
In(Genode::Entrypoint &ep)
In(Genode::Env &env)
:
_ep(ep),
_notify_dispatcher(ep, *this, &Audio_in::In::_handle_notify)
_env(env),
_notify_dispatcher(env.ep(), *this, &Audio_in::In::_handle_notify)
{ _record_packet(); }
Signal_context_capability sigh() { return _notify_dispatcher; }
@ -453,7 +453,7 @@ class Audio_in::Root : public Audio_in::Root_component
{
private:
Genode::Entrypoint &_ep;
Genode::Env &_env;
Signal_context_capability _cap;
protected:
@ -466,14 +466,14 @@ class Audio_in::Root : public Audio_in::Root_component
sizeof(channel_name),
"left");
In::channel_number(channel_name, &channel_number);
return new (md_alloc()) Session_component(channel_number, _cap);
return new (md_alloc()) Session_component(_env, channel_number, _cap);
}
public:
Root(Genode::Entrypoint &ep, Allocator &md_alloc,
Root(Genode::Env &env, Allocator &md_alloc,
Signal_context_capability cap)
: Root_component(&ep.rpc_ep(), &md_alloc), _ep(ep), _cap(cap) { }
: Root_component(env.ep(), md_alloc), _env(env), _cap(cap) { }
};
@ -484,13 +484,12 @@ class Audio_in::Root : public Audio_in::Root_component
struct Main
{
Genode::Env &env;
Genode::Entrypoint &ep;
Genode::Heap heap { &env.ram(), &env.rm() };
Genode::Attached_rom_dataspace config { env, "config" };
Genode::Signal_handler<Main> config_update_dispatcher {
ep, *this, &Main::handle_config_update };
env.ep(), *this, &Main::handle_config_update };
void handle_config_update()
{
@ -499,7 +498,7 @@ struct Main
Audio::update_config(config.xml());
}
Main(Genode::Env &env) : env(env), ep(env.ep())
Main(Genode::Env &env) : env(env)
{
Audio::init_driver(env, heap, config.xml());
@ -509,21 +508,21 @@ struct Main
/* playback */
if (config.xml().attribute_value("playback", true)) {
static Audio_out::Out out(ep);
static Audio_out::Out out(env);
Audio::play_sigh(out.sigh());
static Audio_out::Root out_root(ep, heap, out.data_avail());
env.parent().announce(ep.manage(out_root));
static Audio_out::Root out_root(env, heap, out.data_avail());
env.parent().announce(env.ep().manage(out_root));
Genode::log("--- BSD Audio driver enable playback ---");
}
/* recording */
if (config.xml().attribute_value("recording", true)) {
static Audio_in::In in(ep);
static Audio_in::In in(env);
Audio::record_sigh(in.sigh());
static Audio_in::Root in_root(ep, heap,
static Audio_in::Root in_root(env, heap,
Genode::Signal_context_capability());
env.parent().announce(ep.manage(in_root));
env.parent().announce(env.ep().manage(in_root));
Genode::log("--- BSD Audio driver enable recording ---");
}

View File

@ -7,7 +7,7 @@
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
* Copyright (C) 2015-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@ -16,10 +16,10 @@
/* Genode includes */
#include <audio_out_session/connection.h>
#include <audio_in_session/connection.h>
#include <base/component.h>
#include <base/heap.h>
#include <base/log.h>
#include <base/sleep.h>
#include <dataspace/client.h>
#include <os/config.h>
#include <rom_session/connection.h>
@ -36,12 +36,11 @@ class Recording
{
private:
Genode::Signal_receiver &_sig_rec;
Genode::Signal_dispatcher<Recording> _record_progress;
Genode::Signal_dispatcher<Recording> _record_overrun;
Genode::Signal_handler<Recording> _record_progress;
Genode::Signal_handler<Recording> _record_overrun;
Audio_out::Connection *_audio_out[CHANNELS];
Audio_in::Connection _audio_in { "left" };
Audio_in::Connection _audio_in;
Audio_in::Stream &_stream;
void _play(Audio_in::Packet *ip)
@ -68,7 +67,7 @@ class Recording
_audio_out[c]->submit(op[c]);
}
void _handle_record_progress(unsigned)
void _handle_record_progress()
{
Audio_in::Packet *p = _stream.get(_stream.pos());
@ -83,7 +82,7 @@ class Recording
_stream.increment_position();
}
void _handle_record_overrun(unsigned)
void _handle_record_overrun()
{
unsigned pos = _stream.pos();
unsigned tail = _stream.tail();
@ -101,11 +100,11 @@ class Recording
public:
Recording(Genode::Allocator &md_alloc, Genode::Signal_receiver &sig_rec)
Recording(Genode::Env &env, Genode::Allocator &md_alloc)
:
_sig_rec(sig_rec),
_record_progress(_sig_rec, *this, &Recording::_handle_record_progress),
_record_overrun(_sig_rec, *this, &Recording::_handle_record_overrun),
_record_progress(env.ep(), *this, &Recording::_handle_record_progress),
_record_overrun(env.ep(), *this, &Recording::_handle_record_overrun),
_audio_in(env, "left" ),
_stream(*_audio_in.stream())
{
_audio_in.progress_sigh(_record_progress);
@ -121,24 +120,10 @@ class Recording
}
};
int main(int argc, char *argv[])
void Component::construct(Genode::Env &env)
{
Genode::log("--- Audio_in test ---");
using namespace Genode;
Signal_receiver sig_rec;
Recording record(*env()->heap(), sig_rec);
for (;;) {
Signal sig = sig_rec.wait_for_signal();
Signal_dispatcher_base *dispatcher =
dynamic_cast<Signal_dispatcher_base *>(sig.context());
if (dispatcher)
dispatcher->dispatch(sig.num());
}
return 0;
static Genode::Heap heap { env.ram(), env.rm() };
static Recording record(env, heap);
}

View File

@ -17,6 +17,7 @@
/* Genode includes */
#include <base/env.h>
#include <base/rpc_client.h>
#include <base/attached_dataspace.h>
#include <audio_in_session/audio_in_session.h>
@ -43,6 +44,8 @@ class Audio_in::Session_client : public Genode::Rpc_client<Session>
{
private:
Genode::Attached_dataspace _shared_ds;
Signal _progress;
Genode::Signal_transmitter _data_avail;
@ -55,14 +58,15 @@ class Audio_in::Session_client : public Genode::Rpc_client<Session>
* \param session session capability
* \param progress_signal true, install 'progress_signal' receiver
*/
Session_client(Genode::Capability<Session> session,
Session_client(Genode::Region_map &rm,
Genode::Capability<Session> session,
bool progress_signal)
:
Genode::Rpc_client<Session>(session),
_shared_ds(rm, call<Rpc_dataspace>()),
_data_avail(call<Rpc_data_avail_sigh>())
{
/* ask server for stream data space and attach it */
_stream = static_cast<Stream *>(Genode::env()->rm_session()->attach(call<Rpc_dataspace>()));
_stream = _shared_ds.local_addr<Stream>();
if (progress_signal)
progress_sigh(_progress.cap);

View File

@ -44,20 +44,7 @@ struct Audio_in::Connection : Genode::Connection<Session>, Audio_in::Session_cli
Connection(Genode::Env &env, char const *channel, bool progress_signal = false)
:
Genode::Connection<Session>(env, _session(env.parent(), channel)),
Session_client(cap(), progress_signal)
{ }
/**
* Constructor
*
* \noapi
* \deprecated Use the constructor with 'Env &' as first
* argument instead
*/
Connection(char const *channel, bool progress_signal = false)
:
Genode::Connection<Session>(_session(*Genode::env()->parent(), channel)),
Session_client(cap(), progress_signal)
Session_client(env.rm(), cap(), progress_signal)
{ }
};

View File

@ -17,6 +17,7 @@
/* Genode includes */
#include <base/env.h>
#include <base/rpc_server.h>
#include <base/attached_ram_dataspace.h>
#include <audio_in_session/audio_in_session.h>
@ -28,31 +29,22 @@ class Audio_in::Session_rpc_object : public Genode::Rpc_object<Audio_in::Session
{
protected:
bool _stopped; /* state */
Genode::Ram_dataspace_capability _ds; /* contains Audio_in stream */
Genode::Attached_ram_dataspace _ds; /* contains Audio_in stream */
Genode::Signal_context_capability _data_cap;
Genode::Signal_context_capability _progress_cap;
Genode::Signal_context_capability _overrun_cap;
bool _stopped; /* state */
public:
Session_rpc_object(Genode::Signal_context_capability data_cap)
Session_rpc_object(Genode::Env &env, Genode::Signal_context_capability data_cap)
:
_stopped(true), _data_cap(data_cap)
_ds(env.ram(), env.rm(), sizeof(Stream)),
_data_cap(data_cap), _stopped(true)
{
using namespace Genode;
_ds = env()->ram_session()->alloc(sizeof(Stream));
_stream = static_cast<Stream *>(env()->rm_session()->attach(_ds));
}
virtual ~Session_rpc_object()
{
if (_ds.valid()) {
Genode::env()->rm_session()->detach(_stream);
Genode::env()->ram_session()->free(_ds);
}
_stream = _ds.local_addr<Stream>();
}
@ -77,7 +69,7 @@ class Audio_in::Session_rpc_object : public Genode::Rpc_object<Audio_in::Session
void start() { _stopped = false; }
void stop() { _stopped = true; }
Genode::Dataspace_capability dataspace() { return _ds; }
Genode::Dataspace_capability dataspace() { return _ds.cap(); }
/**********************************

View File

@ -16,6 +16,7 @@
#include <base/env.h>
#include <base/rpc_client.h>
#include <base/attached_dataspace.h>
#include <audio_out_session/audio_out_session.h>
namespace Audio_out {
@ -41,6 +42,8 @@ class Audio_out::Session_client : public Genode::Rpc_client<Session>
{
private:
Genode::Attached_dataspace _shared_ds;
Signal _progress;
Signal _alloc;
@ -51,18 +54,20 @@ class Audio_out::Session_client : public Genode::Rpc_client<Session>
/**
* Constructor
*
* \param rm region map for attaching shared buffer
* \param session session capability
* \param alloc_signal true, install 'alloc_signal' receiver
* \param progress_signal true, install 'progress_signal' receiver
*/
Session_client(Genode::Capability<Session> session, bool alloc_signal,
bool progress_signal)
Session_client(Genode::Region_map &rm,
Genode::Capability<Session> session,
bool alloc_signal, bool progress_signal)
:
Genode::Rpc_client<Session>(session),
_shared_ds(rm, call<Rpc_dataspace>()),
_data_avail(call<Rpc_data_avail_sigh>())
{
/* ask server for stream data space and attach it */
_stream = static_cast<Stream *>(Genode::env()->rm_session()->attach(call<Rpc_dataspace>()));
_stream = _shared_ds.local_addr<Stream>();
if (progress_signal)
progress_sigh(_progress.cap);

View File

@ -50,7 +50,7 @@ struct Audio_out::Connection : Genode::Connection<Session>, Audio_out::Session_c
bool progress_signal = false)
:
Genode::Connection<Session>(env, _session(env.parent(), channel)),
Session_client(cap(), alloc_signal, progress_signal)
Session_client(env.rm(), cap(), alloc_signal, progress_signal)
{ }
/**
@ -65,7 +65,7 @@ struct Audio_out::Connection : Genode::Connection<Session>, Audio_out::Session_c
bool progress_signal = false)
:
Genode::Connection<Session>(_session(*Genode::env()->parent(), channel)),
Session_client(cap(), alloc_signal, progress_signal)
Session_client(*Genode::env()->rm_session(), cap(), alloc_signal, progress_signal)
{ }
};

View File

@ -16,6 +16,7 @@
#include <base/env.h>
#include <base/rpc_server.h>
#include <base/attached_ram_dataspace.h>
#include <audio_out_session/audio_out_session.h>
@ -27,33 +28,25 @@ class Audio_out::Session_rpc_object : public Genode::Rpc_object<Audio_out::Sessi
{
protected:
bool _stopped; /* state */
Genode::Ram_dataspace_capability _ds; /* contains Audio_out_stream */
Genode::Signal_transmitter _progress;
Genode::Signal_transmitter _alloc;
Genode::Attached_ram_dataspace _ds; /* contains Audio_out stream */
Genode::Signal_transmitter _progress;
Genode::Signal_transmitter _alloc;
Genode::Signal_context_capability _data_cap;
bool _stopped; /* state */
bool _progress_sigh; /* progress signal on/off */
bool _alloc_sigh; /* alloc signal on/off */
public:
Session_rpc_object(Genode::Signal_context_capability data_cap)
Session_rpc_object(Genode::Env &env, Genode::Signal_context_capability data_cap)
:
_stopped(true), _data_cap(data_cap),
_progress_sigh(false), _alloc_sigh(false)
_ds(env.ram(), env.rm(), sizeof(Stream)),
_data_cap(data_cap),
_stopped(true), _progress_sigh(false), _alloc_sigh(false)
{
_ds = Genode::env()->ram_session()->alloc(sizeof(Stream));
_stream = static_cast<Stream *>(Genode::env()->rm_session()->attach(_ds));
}
virtual ~Session_rpc_object()
{
if (_ds.valid()) {
Genode::env()->rm_session()->detach(_stream);
Genode::env()->ram_session()->free(_ds);
}
_stream = _ds.local_addr<Stream>();
}
@ -84,7 +77,7 @@ class Audio_out::Session_rpc_object : public Genode::Rpc_object<Audio_out::Sessi
void start() { _stopped = false; }
void stop() { _stopped = true; }
Genode::Dataspace_capability dataspace() { return _ds; }
Genode::Dataspace_capability dataspace() { return _ds.cap(); }
/**********************************

View File

@ -55,9 +55,9 @@ class Audio_out::Session_component : public Audio_out::Session_rpc_object
public:
Session_component(Channel_number channel, Signal_context_capability data_cap)
Session_component(Genode::Env &env, Channel_number channel, Signal_context_capability data_cap)
:
Session_rpc_object(data_cap),
Session_rpc_object(env, data_cap),
_channel(channel)
{
Audio_out::channel_acquired[_channel] = this;
@ -239,6 +239,8 @@ class Audio_out::Root : public Audio_out::Root_component
{
private:
Genode::Env &_env;
Signal_context_capability _data_cap;
protected:
@ -253,14 +255,14 @@ class Audio_out::Root : public Audio_out::Root_component
channel_number_from_string(channel_name, &channel_number);
return new (md_alloc())
Session_component(channel_number, _data_cap);
Session_component(_env, channel_number, _data_cap);
}
public:
Root(Genode::Entrypoint &ep, Allocator *md_alloc,
Root(Genode::Env &env, Allocator &md_alloc,
Signal_context_capability data_cap)
: Root_component(&ep.rpc_ep(), md_alloc), _data_cap(data_cap)
: Root_component(env.ep(), md_alloc), _env(env), _data_cap(data_cap)
{ }
};
@ -293,8 +295,7 @@ struct Audio_out::Main
audio_drv_start();
static Audio_out::Out out(env);
static Audio_out::Root root(env.ep(), &heap,
out.data_avail_sigh());
static Audio_out::Root root(env, heap, out.data_avail_sigh());
env.parent().announce(env.ep().manage(root));
Genode::log("--- start Audio_out ALSA driver ---");
}

View File

@ -124,8 +124,9 @@ struct Audio_out::Session_elem : Audio_out::Session_rpc_object,
float volume { 0.f };
bool muted { true };
Session_elem(char const *label, Genode::Signal_context_capability data_cap)
: Session_rpc_object(data_cap), label(label) { }
Session_elem(Genode::Env & env,
char const *label, Genode::Signal_context_capability data_cap)
: Session_rpc_object(env, data_cap), label(label) { }
Packet *get_packet(unsigned offset) {
return stream()->get(stream()->pos() + offset); }
@ -608,10 +609,11 @@ class Audio_out::Session_component : public Audio_out::Session_elem
public:
Session_component(char const *label,
Session_component(Genode::Env &env,
char const *label,
Channel::Number number,
Mixer &mixer)
: Session_elem(label, mixer.sig_cap()), _mixer(mixer)
: Session_elem(env, label, mixer.sig_cap()), _mixer(mixer)
{
Session_elem::number = number;
_mixer.add_session(Session_elem::number, *this);
@ -647,8 +649,9 @@ class Audio_out::Root : public Audio_out::Root_component
{
private:
Mixer &_mixer;
int _sessions = { 0 };
Genode::Env &_env;
Mixer &_mixer;
int _sessions = { 0 };
Session_component *_create_session(const char *args)
{
@ -681,7 +684,7 @@ class Audio_out::Root : public Audio_out::Root_component
throw Root::Invalid_args();
Session_component *session = new (md_alloc())
Session_component(label, (Channel::Number)ch, _mixer);
Session_component(_env, label, (Channel::Number)ch, _mixer);
if (++_sessions == 1) _mixer.start();
return session;
@ -696,10 +699,10 @@ class Audio_out::Root : public Audio_out::Root_component
public:
Root(Genode::Entrypoint &ep,
Root(Genode::Env &env,
Mixer &mixer,
Genode::Allocator &md_alloc)
: Root_component(&ep.rpc_ep(), &md_alloc), _mixer(mixer) { }
: Root_component(env.ep(), md_alloc), _env(env), _mixer(mixer) { }
};
@ -716,7 +719,7 @@ struct Mixer::Main
Genode::Sliced_heap heap { env.ram(), env.rm() };
Audio_out::Mixer mixer = { env };
Audio_out::Root root = { env.ep(), mixer, heap };
Audio_out::Root root = { env, mixer, heap };
Main(Genode::Env &env) : env(env)
{

View File

@ -5,7 +5,7 @@
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
* Copyright (C) 2015-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
@ -341,7 +341,7 @@ static int genode_init_in(HWVoiceIn *hw, audsettings_t *as)
GenodeVoiceIn *in = (GenodeVoiceIn*)hw;
try {
in->audio = new (vmm_heap()) Audio_in::Connection("left");
in->audio = new (vmm_heap()) Audio_in::Connection(genode_env(), "left");
} catch (...) {
Genode::error("could not establish Audio_in connection");
return -1;