diff --git a/repos/dde_bsd/run/audio_in.run b/repos/dde_bsd/run/audio_in.run new file mode 100644 index 000000000..b1709caa4 --- /dev/null +++ b/repos/dde_bsd/run/audio_in.run @@ -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 { + + + + + + + + + + + + + + + + + + + + + } + +append_platform_drv_config + +append 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 diff --git a/repos/dde_bsd/src/test/audio_in/README b/repos/dde_bsd/src/test/audio_in/README new file mode 100644 index 000000000..a834a0e59 --- /dev/null +++ b/repos/dde_bsd/src/test/audio_in/README @@ -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. diff --git a/repos/dde_bsd/src/test/audio_in/main.cc b/repos/dde_bsd/src/test/audio_in/main.cc new file mode 100644 index 000000000..a9916a926 --- /dev/null +++ b/repos/dde_bsd/src/test/audio_in/main.cc @@ -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 +#include +#include +#include +#include +#include +#include + + +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 _record_progress; + Genode::Signal_dispatcher _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(sig.context()); + + if (dispatcher) + dispatcher->dispatch(sig.num()); + } + + return 0; +} diff --git a/repos/dde_bsd/src/test/audio_in/target.mk b/repos/dde_bsd/src/test/audio_in/target.mk new file mode 100644 index 000000000..925bf4b82 --- /dev/null +++ b/repos/dde_bsd/src/test/audio_in/target.mk @@ -0,0 +1,3 @@ +TARGET = test-audio_in +SRC_CC = main.cc +LIBS = base config