mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
dde_bsd: add Audio_in test application
This test is a simple audio monitor that plays all recorded frames back. Issue #1644.
This commit is contained in:
parent
8a34d21577
commit
fb761283a2
85
repos/dde_bsd/run/audio_in.run
Normal file
85
repos/dde_bsd/run/audio_in.run
Normal file
@ -0,0 +1,85 @@
|
||||
assert_spec x86
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
drivers/audio_out
|
||||
test/audio_in
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Config
|
||||
#
|
||||
|
||||
append config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="SIGNAL" />
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
<start name="audio_out_drv">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides>
|
||||
<service name="Audio_out"/>
|
||||
<service name="Audio_in"/>
|
||||
</provides>
|
||||
<config recording="yes">
|
||||
<mixer field="outputs.master" value="255"/>
|
||||
<mixer field="record.adc-0:1_source" value="sel2"/>
|
||||
<mixer field="record.adc-0:1" value="255"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="test-audio_in">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
</start>
|
||||
</config>}
|
||||
|
||||
install_config $config
|
||||
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
set boot_modules {
|
||||
core init timer audio_out_drv test-audio_in
|
||||
}
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -m 128 -nographic -soundhw es1370 "
|
||||
|
||||
run_genode_until forever
|
3
repos/dde_bsd/src/test/audio_in/README
Normal file
3
repos/dde_bsd/src/test/audio_in/README
Normal file
@ -0,0 +1,3 @@
|
||||
This test captures input from an Audio_in session and directly plays
|
||||
all packets by sending them to the Audio_out session. It is merely a
|
||||
simple audio monitor program.
|
144
repos/dde_bsd/src/test/audio_in/main.cc
Normal file
144
repos/dde_bsd/src/test/audio_in/main.cc
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* \brief Audio-in test implementation
|
||||
* \author Josef Soentgen
|
||||
* \date 2015-05-11
|
||||
*
|
||||
* The test program records on channel.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <audio_out_session/connection.h>
|
||||
#include <audio_in_session/connection.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <os/config.h>
|
||||
#include <rom_session/connection.h>
|
||||
|
||||
|
||||
enum {
|
||||
LEFT = 0,
|
||||
RIGHT = 1,
|
||||
CHANNELS = 2,
|
||||
FRAME_SIZE = sizeof(float),
|
||||
PERIOD_SIZE = FRAME_SIZE * Audio_in::PERIOD, /* size of period frame */
|
||||
};
|
||||
|
||||
|
||||
class Recording
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Signal_receiver &_sig_rec;
|
||||
Genode::Signal_dispatcher<Recording> _record_progress;
|
||||
Genode::Signal_dispatcher<Recording> _record_overrun;
|
||||
|
||||
Audio_out::Connection *_audio_out[CHANNELS];
|
||||
Audio_in::Connection _audio_in { "left" };
|
||||
Audio_in::Stream &_stream;
|
||||
|
||||
void _play(Audio_in::Packet *ip)
|
||||
{
|
||||
float *in = ip->content();
|
||||
|
||||
Audio_out::Packet *op[CHANNELS];
|
||||
|
||||
/* get left channel packet pos and sync right channel */
|
||||
try {
|
||||
op[LEFT] = _audio_out[LEFT]->stream()->alloc();
|
||||
unsigned pos = _audio_out[LEFT]->stream()->packet_position(op[LEFT]);
|
||||
op[RIGHT] = _audio_out[RIGHT]->stream()->get(pos);
|
||||
} catch (...) { return; }
|
||||
|
||||
for (int c = 0; c < CHANNELS; c++) {
|
||||
float *out = op[c]->content();
|
||||
for (int i = 0; i < Audio_in::PERIOD; i++) {
|
||||
out[i] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < CHANNELS; c++)
|
||||
_audio_out[c]->submit(op[c]);
|
||||
}
|
||||
|
||||
void _handle_record_progress(unsigned)
|
||||
{
|
||||
Audio_in::Packet *p = _stream.get(_stream.pos());
|
||||
|
||||
if (!p->valid())
|
||||
return;
|
||||
|
||||
_play(p);
|
||||
|
||||
p->invalidate();
|
||||
p->mark_as_recorded();
|
||||
|
||||
_stream.increment_position();
|
||||
}
|
||||
|
||||
void _handle_record_overrun(unsigned)
|
||||
{
|
||||
unsigned pos = _stream.pos();
|
||||
unsigned tail = _stream.tail();
|
||||
|
||||
PWRN("record overrun, pos: %u tail: %u overriden: %u",
|
||||
pos, tail, tail - pos);
|
||||
|
||||
/*
|
||||
* Normally you would handle this case properly by saving all
|
||||
* packet that have not been already overriden. For simplicity
|
||||
* we just discard all packets by setting pos to current tail.
|
||||
*/
|
||||
_stream.pos(tail);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Recording(Genode::Allocator &md_alloc, Genode::Signal_receiver &sig_rec)
|
||||
:
|
||||
_sig_rec(sig_rec),
|
||||
_record_progress(_sig_rec, *this, &Recording::_handle_record_progress),
|
||||
_record_overrun(_sig_rec, *this, &Recording::_handle_record_overrun),
|
||||
_stream(*_audio_in.stream())
|
||||
{
|
||||
_audio_in.progress_sigh(_record_progress);
|
||||
_audio_in.overrun_sigh(_record_overrun);
|
||||
|
||||
_audio_out[0] = new (&md_alloc) Audio_out::Connection("front left", true);
|
||||
_audio_out[1] = new (&md_alloc) Audio_out::Connection("front right", true);
|
||||
|
||||
_audio_out[0]->start();
|
||||
_audio_out[1]->start();
|
||||
|
||||
_audio_in.start();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
PDBG("--- Audio_in test ---\n");
|
||||
|
||||
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;
|
||||
}
|
3
repos/dde_bsd/src/test/audio_in/target.mk
Normal file
3
repos/dde_bsd/src/test/audio_in/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET = test-audio_in
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config
|
Loading…
x
Reference in New Issue
Block a user