genode/repos/os/include/audio_in_session/client.h
Josef Söntgen 61f5ca1e4d os: add Audio_in session for recording audio
In line with the Audio_out session a Audio_in session is used to
record audio frames. Like in the Audio_out session shared memory
in form of the Audio_in::Stream is used to transport the frames
from the server to the client. These frames consist of single
channel (mono) samples. An Audio_in::Packet always contains a full
period of frames.

A Audio_in server captures frames and puts them into the
Audio_in::Stream. To do so the server allocates a Audio_in::Packet
from the packet queue embedded in the Audio_in::Stream. If the queue
is already full, the server will override packets and notify the
client by submitting the 'overrun' signal. The client has to cope
with this situation, e.g., by saving packets more frequently.

A client will also receive a 'progress' signal from the server when
a new Audio_in::Packet was submitted to the packet queue.

Fixes #1644.
2015-08-21 10:59:46 +02:00

120 lines
2.5 KiB
C++

/*
* \brief Client-side Audio_in-session
* \author Josef Soentgen
* \date 2015-05-08
*/
/*
* Copyright (C) 2015 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.
*/
#ifndef _INCLUDE__AUDIO_IN_SESSION__CLIENT_H_
#define _INCLUDE__AUDIO_IN_SESSION__CLIENT_H_
/* Genode includes */
#include <base/env.h>
#include <base/rpc_client.h>
#include <audio_in_session/audio_in_session.h>
namespace Audio_in {
struct Signal;
struct Session_client;
}
struct Audio_in::Signal
{
Genode::Signal_receiver recv;
Genode::Signal_context context;
Genode::Signal_context_capability cap;
Signal() : cap(recv.manage(&context)) { }
void wait() { recv.wait_for_signal(); }
};
class Audio_in::Session_client : public Genode::Rpc_client<Session>
{
private:
Signal _progress;
Genode::Signal_transmitter _data_avail;
public:
/**
* Constructor
*
* \param session session capability
* \param progress_signal true, install 'progress_signal' receiver
*/
Session_client(Genode::Capability<Session> session,
bool progress_signal)
:
Genode::Rpc_client<Session>(session),
_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>()));
if (progress_signal)
progress_sigh(_progress.cap);
}
/*************
** Signals **
*************/
void progress_sigh(Genode::Signal_context_capability sigh) {
call<Rpc_progress_sigh>(sigh); }
void overrun_sigh(Genode::Signal_context_capability sigh) {
call<Rpc_overrun_sigh>(sigh); }
Genode::Signal_context_capability data_avail_sigh() {
return Genode::Signal_context_capability(); }
/***********************
** Session interface **
***********************/
void start()
{
call<Rpc_start>();
/* reset tail pointer */
stream()->reset();
}
void stop() { call<Rpc_stop>(); }
/**********************************
** Session interface extensions **
**********************************/
/**
* Wait for progress signal
*/
void wait_for_progress()
{
if (!_progress.cap.valid()) {
PWRN("Progress signal is not installed, will not block "
"(enable in 'Audio_in::Connection')");
return;
}
_progress.wait();
}
};
#endif /* _INCLUDE__AUDIO_IN_SESSION__CLIENT_H_ */