mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 06:57:51 +00:00
parent
33402e407f
commit
3f656bcf84
@ -1,11 +1,15 @@
|
|||||||
<runtime ram="8M" caps="100" binary="black_hole">
|
<runtime ram="8M" caps="100" binary="black_hole">
|
||||||
|
|
||||||
<provides>
|
<provides>
|
||||||
|
<audio_in/>
|
||||||
<audio_out/>
|
<audio_out/>
|
||||||
|
<capture/>
|
||||||
</provides>
|
</provides>
|
||||||
|
|
||||||
<config>
|
<config>
|
||||||
|
<audio_in/>
|
||||||
<audio_out/>
|
<audio_out/>
|
||||||
|
<capture/>
|
||||||
</config>
|
</config>
|
||||||
|
|
||||||
<content>
|
<content>
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
base
|
base
|
||||||
|
audio_in_session
|
||||||
audio_out_session
|
audio_out_session
|
||||||
|
capture_session
|
||||||
|
os
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
The 'black_hole' component provides dummy implementations of common
|
The 'black_hole' component provides dummy implementations of common
|
||||||
session interfaces.
|
session interfaces.
|
||||||
|
|
||||||
At this time, only the 'Audio_out' session is provided if enabled
|
At this time, the following sessions are provided if enabled
|
||||||
in the configuration of the component:
|
in the configuration of the component:
|
||||||
|
|
||||||
|
* Audio_in
|
||||||
|
* Audio_out
|
||||||
|
* Capture
|
||||||
|
|
||||||
<config>
|
<config>
|
||||||
|
<audio_in/>
|
||||||
<audio_out/>
|
<audio_out/>
|
||||||
|
<capture/>
|
||||||
</config>
|
</config>
|
||||||
|
159
repos/os/src/server/black_hole/audio_in.h
Normal file
159
repos/os/src/server/black_hole/audio_in.h
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* \brief 'Audio_in' part of black hole component
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2021-07-07
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021-2022 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AUDIO_IN_H_
|
||||||
|
#define _AUDIO_IN_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <audio_in_session/rpc_object.h>
|
||||||
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Audio_in
|
||||||
|
{
|
||||||
|
class Session_component_base;
|
||||||
|
class Session_component;
|
||||||
|
class Root;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This base struct is needed to get the 'Signal_handler' constructed
|
||||||
|
* before the 'Session_rpc_object' constructor is called with the handler
|
||||||
|
* as argument.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Audio_in::Session_component_base
|
||||||
|
{
|
||||||
|
Genode::Signal_handler<Session_component_base> _data_available_handler;
|
||||||
|
Timer::One_shot_timeout<Session_component_base> _timeout;
|
||||||
|
|
||||||
|
virtual void _handle_data_available() = 0;
|
||||||
|
virtual void _handle_timeout(Genode::Duration) = 0;
|
||||||
|
|
||||||
|
Session_component_base(Genode::Env &env, Timer::Connection &timer)
|
||||||
|
: _data_available_handler(env.ep(),
|
||||||
|
*this,
|
||||||
|
&Session_component_base::_handle_data_available),
|
||||||
|
_timeout(timer, *this, &Session_component_base::_handle_timeout)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual ~Session_component_base() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Audio_in::Session_component : Audio_in::Session_component_base,
|
||||||
|
public Audio_in::Session_rpc_object
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Microseconds _delay {
|
||||||
|
(Audio_in::PERIOD * 1000 * 1000) / Audio_in::SAMPLE_RATE };
|
||||||
|
|
||||||
|
void _handle_data_available() override
|
||||||
|
{
|
||||||
|
_timeout.schedule(_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handle_timeout(Genode::Duration) override
|
||||||
|
{
|
||||||
|
if (!active())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Packet *p = stream()->alloc();
|
||||||
|
|
||||||
|
Genode::memset(p->content(), 0,
|
||||||
|
Audio_in::PERIOD * Audio_in::SAMPLE_SIZE);
|
||||||
|
|
||||||
|
stream()->submit(p);
|
||||||
|
|
||||||
|
progress_submit();
|
||||||
|
|
||||||
|
_timeout.schedule(_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Session_component(Genode::Env &env, Timer::Connection &timer)
|
||||||
|
: Session_component_base(env, timer),
|
||||||
|
Session_rpc_object(env, _data_available_handler)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~Session_component()
|
||||||
|
{
|
||||||
|
if (Session_rpc_object::active()) stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() override
|
||||||
|
{
|
||||||
|
Session_rpc_object::start();
|
||||||
|
_timeout.schedule(_delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() override
|
||||||
|
{
|
||||||
|
Session_rpc_object::stop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace Audio_in {
|
||||||
|
typedef Genode::Root_component<Session_component, Genode::Multiple_clients> Root_component;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Audio_in::Root : public Audio_in::Root_component
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Env &_env;
|
||||||
|
Timer::Connection _timer;
|
||||||
|
|
||||||
|
Session_component *_create_session(const char *args) override
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
size_t ram_quota =
|
||||||
|
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||||
|
|
||||||
|
size_t session_size = align_addr(sizeof(Session_component), 12);
|
||||||
|
|
||||||
|
if ((ram_quota < session_size) ||
|
||||||
|
(sizeof(Stream) > ram_quota - session_size)) {
|
||||||
|
Genode::error("insufficient 'ram_quota', got ", ram_quota, ", "
|
||||||
|
"need ", sizeof(Stream) + session_size);
|
||||||
|
throw Insufficient_ram_quota();
|
||||||
|
}
|
||||||
|
|
||||||
|
Session_component *session = new (md_alloc())
|
||||||
|
Session_component(_env, _timer);
|
||||||
|
|
||||||
|
return session;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _destroy_session(Session_component *session) override
|
||||||
|
{
|
||||||
|
Genode::destroy(md_alloc(), session);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Root(Genode::Env &env,
|
||||||
|
Genode::Allocator &md_alloc)
|
||||||
|
: Root_component(env.ep(), md_alloc),
|
||||||
|
_env(env), _timer(env) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _AUDIO_IN_H_ */
|
150
repos/os/src/server/black_hole/capture.h
Normal file
150
repos/os/src/server/black_hole/capture.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* \brief 'Capture' part of black hole component
|
||||||
|
* \author Christian Prochaska
|
||||||
|
* \date 2021-09-24
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021-2022 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CAPTURE_H_
|
||||||
|
#define _CAPTURE_H_
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/session_object.h>
|
||||||
|
#include <capture_session/capture_session.h>
|
||||||
|
|
||||||
|
#include <audio_out_session/rpc_object.h>
|
||||||
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Capture
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
class Session_component;
|
||||||
|
class Root;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Capture::Session_component : public Session_object<Capture::Session>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Env &_env;
|
||||||
|
|
||||||
|
Constrained_ram_allocator _ram;
|
||||||
|
|
||||||
|
Constructible<Attached_ram_dataspace> _buffer { };
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Session_component(Env &env,
|
||||||
|
Resources const &resources,
|
||||||
|
Label const &label,
|
||||||
|
Diag const &diag)
|
||||||
|
:
|
||||||
|
Session_object(env.ep(), resources, label, diag),
|
||||||
|
_env(env),
|
||||||
|
_ram(env.ram(), _ram_quota_guard(), _cap_quota_guard())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~Session_component() { }
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
** Capture session interface **
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
Area screen_size() const override
|
||||||
|
{
|
||||||
|
return Area(640, 480);
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_size_sigh(Signal_context_capability) override { }
|
||||||
|
|
||||||
|
void buffer(Area size) override
|
||||||
|
{
|
||||||
|
if (size.count() == 0) {
|
||||||
|
_buffer.destruct();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer.construct(_ram, _env.rm(), buffer_bytes(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
Dataspace_capability dataspace() override
|
||||||
|
{
|
||||||
|
if (_buffer.constructed())
|
||||||
|
return _buffer->cap();
|
||||||
|
|
||||||
|
return Dataspace_capability();
|
||||||
|
}
|
||||||
|
|
||||||
|
Affected_rects capture_at(Point) override
|
||||||
|
{
|
||||||
|
return Affected_rects();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace Capture {
|
||||||
|
typedef Genode::Root_component<Session_component, Genode::Multiple_clients> Root_component;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Capture::Root : public Capture::Root_component
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Genode::Env &_env;
|
||||||
|
|
||||||
|
Session_component *_create_session(const char *args) override
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
size_t ram_quota =
|
||||||
|
Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||||
|
|
||||||
|
size_t session_size = align_addr(sizeof(Session_component), 12);
|
||||||
|
|
||||||
|
if ((ram_quota < session_size)) {
|
||||||
|
Genode::error("insufficient 'ram_quota', got ", ram_quota, ", "
|
||||||
|
"need ", session_size);
|
||||||
|
throw Insufficient_ram_quota();
|
||||||
|
}
|
||||||
|
|
||||||
|
Session_component *session = new (md_alloc())
|
||||||
|
Session_component(_env,
|
||||||
|
session_resources_from_args(args),
|
||||||
|
session_label_from_args(args),
|
||||||
|
session_diag_from_args(args));
|
||||||
|
|
||||||
|
return session;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void _upgrade_session(Session_component *s, const char *args) override
|
||||||
|
{
|
||||||
|
s->upgrade(ram_quota_from_args(args));
|
||||||
|
s->upgrade(cap_quota_from_args(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _destroy_session(Session_component *session) override
|
||||||
|
{
|
||||||
|
Genode::destroy(md_alloc(), session);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Root(Genode::Env &env,
|
||||||
|
Genode::Allocator &md_alloc)
|
||||||
|
: Root_component(env.ep(), md_alloc),
|
||||||
|
_env(env) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _CAPTURE_H_ */
|
@ -21,7 +21,9 @@
|
|||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
|
#include "audio_in.h"
|
||||||
#include "audio_out.h"
|
#include "audio_out.h"
|
||||||
|
#include "capture.h"
|
||||||
|
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
@ -36,16 +38,28 @@ struct Black_hole::Main
|
|||||||
|
|
||||||
Genode::Sliced_heap heap { env.ram(), env.rm() };
|
Genode::Sliced_heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
|
Genode::Constructible<Audio_in::Root> audio_in_root { };
|
||||||
Genode::Constructible<Audio_out::Root> audio_out_root { };
|
Genode::Constructible<Audio_out::Root> audio_out_root { };
|
||||||
|
Genode::Constructible<Capture::Root> capture_root { };
|
||||||
|
|
||||||
Main(Genode::Env &env) : env(env)
|
Main(Genode::Env &env) : env(env)
|
||||||
{
|
{
|
||||||
Genode::Attached_rom_dataspace _config_rom { env, "config" };
|
Genode::Attached_rom_dataspace _config_rom { env, "config" };
|
||||||
|
|
||||||
|
if (_config_rom.xml().has_sub_node("audio_in")) {
|
||||||
|
audio_in_root.construct(env, heap);
|
||||||
|
env.parent().announce(env.ep().manage(*audio_in_root));
|
||||||
|
}
|
||||||
|
|
||||||
if (_config_rom.xml().has_sub_node("audio_out")) {
|
if (_config_rom.xml().has_sub_node("audio_out")) {
|
||||||
audio_out_root.construct(env, heap);
|
audio_out_root.construct(env, heap);
|
||||||
env.parent().announce(env.ep().manage(*audio_out_root));
|
env.parent().announce(env.ep().manage(*audio_out_root));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_config_rom.xml().has_sub_node("capture")) {
|
||||||
|
capture_root.construct(env, heap);
|
||||||
|
env.parent().announce(env.ep().manage(*capture_root));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user