Skip to content

Commit da743cc

Browse files
cnukenfeske
authored andcommitted
Add rudimentary audio_player based on libav
For further information please look at 'src/app/audio_player/README'. Fixes TUD-OS#41.
1 parent 099ea5a commit da743cc

9 files changed

Lines changed: 1580 additions & 0 deletions

File tree

run/audio_player.run

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#
2+
# Build
3+
#
4+
5+
set build_components {
6+
core init
7+
drivers/timer
8+
drivers/audio
9+
server/report_rom
10+
server/dynamic_rom
11+
app/audio_player
12+
}
13+
14+
source ${genode_dir}/repos/base/run/platform_drv.inc
15+
append_platform_drv_build_components
16+
17+
build $build_components
18+
19+
create_boot_directory
20+
21+
#
22+
# Config
23+
#
24+
25+
append config {
26+
<config>
27+
<parent-provides>
28+
<service name="ROM"/>
29+
<service name="RAM"/>
30+
<service name="IRQ"/>
31+
<service name="IO_MEM"/>
32+
<service name="IO_PORT"/>
33+
<service name="CAP"/>
34+
<service name="PD"/>
35+
<service name="RM"/>
36+
<service name="CPU"/>
37+
<service name="LOG"/>
38+
<service name="SIGNAL" />
39+
</parent-provides>
40+
<default-route>
41+
<any-service> <parent/> <any-child/> </any-service>
42+
</default-route>
43+
<start name="timer">
44+
<resource name="RAM" quantum="1M"/>
45+
<provides><service name="Timer"/></provides>
46+
</start>}
47+
48+
append_platform_drv_config
49+
50+
append config {
51+
<start name="report_rom">
52+
<resource name="RAM" quantum="4M"/>
53+
<provides> <service name="Report"/> <service name="ROM"/> </provides>
54+
<config verbose="yes">
55+
<rom>
56+
<policy label="" report="audio_player -> current_track"/>
57+
</rom>
58+
</config>
59+
</start>
60+
61+
<start name="dynamic_rom">
62+
<resource name="RAM" quantum="4M"/>
63+
<provides><service name="ROM"/></provides>
64+
<config verbose="yes">
65+
<rom name="playlist">
66+
<inline description="initial playlist">
67+
<playlist>
68+
<track path="foo.mp3"/>
69+
<track path="foo.ogg"/>
70+
<track path="foo.flac"/>
71+
</playlist>
72+
</inline>
73+
<sleep milliseconds="30000"/>
74+
<inline description="initial playlist">
75+
<playlist>
76+
<track path="foo.ogg"/>
77+
</playlist>
78+
</inline>
79+
<sleep milliseconds="30000"/>
80+
</rom>
81+
<rom name="audio_player.config">
82+
<inline description="initial config">
83+
<config ld_verbose="yes" state="playing" playlist_mode="repeat">
84+
<report progress="yes" interval="1" playlist="yes"/>
85+
<libc>
86+
<vfs>
87+
<rom name="foo.mp3"/>
88+
<rom name="foo.flac"/>
89+
<rom name="foo.ogg"/>
90+
</vfs>
91+
</libc>
92+
</config>
93+
</inline>
94+
<sleep milliseconds="10000"/>
95+
<inline description="select third track">
96+
<config state="playing" playlist_mode="repeat" selected_track="3"/>
97+
</inline>
98+
<sleep milliseconds="5000"/>
99+
<inline description="select first track">
100+
<config state="playing" playlist_mode="repeat" selected_track="1"/>
101+
</inline>
102+
<sleep milliseconds="5000"/>
103+
<inline description="select second track">
104+
<config state="playing" playlist_mode="repeat" selected_track="2"/>
105+
</inline>
106+
<sleep milliseconds="5000"/>
107+
</rom>
108+
</config>
109+
</start>
110+
111+
<start name="audio_drv">
112+
<resource name="RAM" quantum="8M"/>
113+
<provides> <service name="Audio_out"/> </provides>
114+
<config/>
115+
</start>
116+
117+
<start name="audio_player">
118+
<resource name="RAM" quantum="16M"/>
119+
<configfile name="audio_player.config"/>
120+
<route>
121+
<service name="ROM" label="audio_player.config"> <child name="dynamic_rom"/> </service>
122+
<service name="ROM" label="playlist"> <child name="dynamic_rom"/> </service>
123+
<service name="Report" label="current_track"> <child name="report_rom"/> </service>
124+
<any-service> <parent/> <any-child/> </any-service>
125+
</route>
126+
</start>
127+
</config>}
128+
129+
install_config $config
130+
131+
#
132+
# Check audio files
133+
#
134+
135+
if {[expr ![file exists bin/foo.flac] || ![file exists bin/foo.mp3] || ![file exists bin/foo.ogg]]} {
136+
puts ""
137+
puts "One or all audio files are missing. Please put 'foo.flac', 'foo.mp3' and"
138+
puts "'foo.ogg' into './bin' and execute this run script again. Note, that the"
139+
puts "duration of each of those files has to be below 10 seconds for this run"
140+
puts "script to work properly."
141+
puts ""
142+
exit 1
143+
}
144+
145+
#
146+
# Boot modules
147+
#
148+
149+
set boot_modules {
150+
core init timer dynamic_rom report_rom audio_drv
151+
ld.lib.so libc.lib.so libm.lib.so zlib.lib.so
152+
avcodec.lib.so avformat.lib.so avutil.lib.so
153+
avresample.lib.so pthread.lib.so
154+
audio_player
155+
foo.mp3 foo.flac foo.ogg
156+
}
157+
158+
append_platform_drv_boot_modules
159+
160+
build_boot_image $boot_modules
161+
162+
run_genode_until forever

src/app/audio_player/README

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
This directory contains a rudimentary audio player. It plays all tracks from
2+
a given playlist and reports the currently playing track.
3+
4+
5+
Configuration
6+
~~~~~~~~~~~~~
7+
8+
A typical example configuration looks as follows:
9+
10+
! <config>
11+
! <report progress="yes" interval="3" playlist="yes"/>
12+
! <libc>
13+
! <vfs>
14+
! <rom name="foo.flac"/>
15+
! <rom name="foo.mp3"/>
16+
! <rom name="foo.ogg"/>
17+
! </vfs>
18+
! </libc>
19+
! </config>
20+
21+
The audio player obtains its audio files from the libc VFS. In this example,
22+
the VFS is configured to present three ROM modules as files in the root
23+
directory. In addition the audio player requests another ROM module that
24+
contains the actual playlist:
25+
26+
! <playlist mode="repeat">
27+
! <track path="foo.ogg"/>
28+
! <track path="foo.flac"/>
29+
! </playlist>
30+
31+
The prior mentioned files are then referred to by the subsequent '<track>'
32+
nodes within the '<playlist>' node. How the player processes the playlist is
33+
specified via the 'mode' attribute. Valid values are 'once' and 'repeat'
34+
whereat 'once' is the default mode. Everytime the playlist is altered, the
35+
audio player updates its internal representation of the playlist but keeps
36+
playing the current track till its end.
37+
38+
Playback can be paused, stopped and of course started again by setting the
39+
'state' attribute of the '<config>' node to 'playing', 'paused' or 'stopped'.
40+
The player is automatically stopped if the 'state' attribute is missing.
41+
When playback is started the player starts playing at the first track of the
42+
playlist. Furthermore the player can be instructed to start at a different
43+
track by specifying the number of the track in the 'selected_track' attribute.
44+
This attribute may also be used to select a different track while the player
45+
is playing.
46+
47+
The initial configuration must include the VFS configuration, all following
48+
configurations may safely ommit it.
49+
50+
51+
Status reporting
52+
~~~~~~~~~~~~~~~~
53+
54+
Every time the player changes the track it generates a report that contains
55+
information about the track that is now being played. A typical report looks
56+
like this:
57+
58+
! <current_track id="1" path="foo.ogg" artist="Foobar" album="SNAFU" title="blubb" duration="60000"/>
59+
60+
The duration is given in milliseconds.
61+
62+
When the 'report' node is present in the configuration additional reports
63+
are generated. If the 'progress' attribute is set to 'yes' the player will
64+
report the current progress in the 'current_track' report. The frequencey
65+
of reporting is specified by setting the 'interval' attribute. The interval
66+
is given in seconds. if the 'playlist' attribute is set to 'yes' the
67+
player will generate a report containing the playlist but each '<track>' node
68+
is enriched by the meta information of each track like in the 'current_track'
69+
report.
70+
71+
72+
Example
73+
~~~~~~~
74+
75+
Please refer to the _gems/run/audio_player.run_ script for a practical example of
76+
using the audio player.
77+
78+
There is also a selection of bash scripts in _gems/src/app/audio_player/noux_
79+
which can be used from Noux to control the audio player.

src/app/audio_player/list.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* \brief Slightly improved list
3+
* \author Christian Helmuth
4+
* \date 2014-09-25
5+
*/
6+
7+
/*
8+
* Copyright (C) 2014 Genode Labs GmbH
9+
*
10+
* This file is part of the Genode OS framework, which is distributed
11+
* under the terms of the GNU General Public License version 2.
12+
*/
13+
14+
#ifndef _LIST_H_
15+
#define _LIST_H_
16+
17+
#include <util/list.h>
18+
19+
20+
namespace Util {
21+
template <typename> class List;
22+
template <typename> class List_element;
23+
}
24+
25+
template <typename LT>
26+
class Util::List : private Genode::List<LT>
27+
{
28+
private:
29+
30+
typedef Genode::List<LT> Base;
31+
32+
public:
33+
34+
using Base::Element;
35+
36+
void append(LT const *le)
37+
{
38+
LT *at = nullptr;
39+
40+
for (LT *l = first(); l; l = l->next())
41+
at = l;
42+
43+
Base::insert(le, at);
44+
}
45+
46+
void prepend(LT const *le)
47+
{
48+
Base::insert(le);
49+
}
50+
51+
void insert_before(LT const *le, LT const *at)
52+
{
53+
if (at == first()) {
54+
prepend(le);
55+
return;
56+
} else if (!at) {
57+
append(le);
58+
return;
59+
}
60+
61+
for (LT *l = first(); l; l = l->next())
62+
if (l->next() == at)
63+
at = l;
64+
65+
Base::insert(le, at);
66+
}
67+
68+
69+
/****************************
70+
** Genode::List interface **
71+
****************************/
72+
73+
LT *first() { return Base::first(); }
74+
LT const *first() const { return Base::first(); }
75+
76+
void insert(LT const *le, LT const *at = 0)
77+
{
78+
Base::insert(le, at);
79+
}
80+
81+
void remove(LT const *le)
82+
{
83+
Base::remove(le);
84+
}
85+
};
86+
87+
88+
template <typename T>
89+
class Util::List_element : public Util::List<List_element<T> >::Element
90+
{
91+
private:
92+
93+
T *_object;
94+
95+
public:
96+
97+
List_element(T *object) : _object(object) { }
98+
99+
T *object() const { return _object; }
100+
};
101+
102+
#endif /* _LIST_H_ */

0 commit comments

Comments
 (0)