2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Audio-out test implementation
|
|
|
|
* \author Sebastian Sumpf
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \date 2009-12-03
|
|
|
|
*
|
|
|
|
* The test program plays several tracks simultaneously to the Audio_out
|
|
|
|
* service. See README for the configuration.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 20:44:47 +00:00
|
|
|
* Copyright (C) 2009-2013 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2013-01-10 11:10:41 +00:00
|
|
|
#include <audio_out_session/connection.h>
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
#include <base/log.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
#include <base/sleep.h>
|
2016-11-06 13:19:47 +00:00
|
|
|
#include <base/attached_rom_dataspace.h>
|
2012-12-20 16:34:33 +00:00
|
|
|
#include <rom_session/connection.h>
|
|
|
|
#include <dataspace/client.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
#include <os/config.h>
|
|
|
|
|
2012-12-20 16:34:33 +00:00
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
using namespace Genode;
|
|
|
|
using namespace Audio_out;
|
|
|
|
|
|
|
|
static const bool verbose = false;
|
|
|
|
|
|
|
|
enum {
|
|
|
|
CHN_CNT = 2, /* number of channels */
|
2012-12-20 16:34:33 +00:00
|
|
|
FRAME_SIZE = sizeof(float),
|
2011-12-22 15:19:25 +00:00
|
|
|
PERIOD_CSIZE = FRAME_SIZE * PERIOD, /* size of channel packet (bytes) */
|
|
|
|
PERIOD_FSIZE = CHN_CNT * PERIOD_CSIZE, /* size of period in file (bytes) */
|
|
|
|
};
|
|
|
|
|
2012-12-20 16:34:33 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
static const char *channel_names[] = { "front left", "front right" };
|
|
|
|
|
|
|
|
|
2016-05-04 10:27:17 +00:00
|
|
|
class Track : Thread_deprecated<8192>
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
2016-12-01 16:37:08 +00:00
|
|
|
Constructible<Audio_out::Connection> _audio_out[CHN_CNT];
|
2016-11-06 13:19:47 +00:00
|
|
|
|
|
|
|
String<64> const _name;
|
|
|
|
|
|
|
|
Attached_rom_dataspace _sample_ds { _name.string() };
|
|
|
|
char const * const _base = _sample_ds.local_addr<char const>();
|
|
|
|
size_t const _size = _sample_ds.size();
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2016-11-06 13:19:47 +00:00
|
|
|
Track(const char *name) : Thread_deprecated("track"), _name(name)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
|
|
|
for (int i = 0; i < CHN_CNT; ++i) {
|
2012-12-20 16:34:33 +00:00
|
|
|
/* allocation signal for first channel only */
|
2016-11-06 13:19:47 +00:00
|
|
|
_audio_out[i].construct(channel_names[i], i == 0);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void entry()
|
|
|
|
{
|
|
|
|
if (verbose)
|
2016-11-06 13:19:47 +00:00
|
|
|
log(_name, " size is ", _size, " bytes "
|
|
|
|
"(attached to ", (void *)_base, ")");
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2012-12-20 16:34:33 +00:00
|
|
|
for (int i = 0; i < CHN_CNT; ++i)
|
|
|
|
_audio_out[i]->start();
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-04-30 12:50:20 +00:00
|
|
|
unsigned cnt = 0;
|
2011-12-22 15:19:25 +00:00
|
|
|
while (1) {
|
|
|
|
|
|
|
|
for (size_t offset = 0, cnt = 1;
|
2016-11-06 13:19:47 +00:00
|
|
|
offset < _size;
|
2011-12-22 15:19:25 +00:00
|
|
|
offset += PERIOD_FSIZE, ++cnt) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The current chunk (in number of frames of one channel)
|
|
|
|
* is the size of the period except at the end of the
|
|
|
|
* file.
|
|
|
|
*/
|
2016-11-06 13:19:47 +00:00
|
|
|
size_t chunk = (offset + PERIOD_FSIZE > _size)
|
|
|
|
? (_size - offset) / CHN_CNT / FRAME_SIZE
|
2011-12-22 15:19:25 +00:00
|
|
|
: PERIOD;
|
|
|
|
|
2012-12-20 16:34:33 +00:00
|
|
|
Packet *p[CHN_CNT];
|
|
|
|
while (1)
|
|
|
|
try {
|
|
|
|
p[0] = _audio_out[0]->stream()->alloc();
|
|
|
|
break;
|
|
|
|
} catch (Audio_out::Stream::Alloc_failed) {
|
|
|
|
_audio_out[0]->wait_for_alloc();
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned pos = _audio_out[0]->stream()->packet_position(p[0]);
|
|
|
|
/* sync other channels with first one */
|
|
|
|
for (int chn = 1; chn < CHN_CNT; ++chn)
|
|
|
|
p[chn] = _audio_out[chn]->stream()->get(pos);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/* copy channel contents into sessions */
|
2016-11-06 13:19:47 +00:00
|
|
|
float *content = (float *)(_base + offset);
|
2011-12-22 15:19:25 +00:00
|
|
|
for (unsigned c = 0; c < CHN_CNT * chunk; c += CHN_CNT)
|
|
|
|
for (int i = 0; i < CHN_CNT; ++i)
|
2012-12-20 16:34:33 +00:00
|
|
|
p[i]->content()[c / 2] = content[c + i];
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/* handle last packet gracefully */
|
|
|
|
if (chunk < PERIOD) {
|
|
|
|
for (int i = 0; i < CHN_CNT; ++i)
|
2012-12-20 16:34:33 +00:00
|
|
|
memset(p[i]->content() + chunk,
|
2011-12-22 15:19:25 +00:00
|
|
|
0, PERIOD_CSIZE - FRAME_SIZE * chunk);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (verbose)
|
2016-11-06 13:19:47 +00:00
|
|
|
log(_name, " submit packet ",
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
_audio_out[0]->stream()->packet_position((p[0])));
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2012-12-20 16:34:33 +00:00
|
|
|
for (int i = 0; i < CHN_CNT; i++)
|
|
|
|
_audio_out[i]->submit(p[i]);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
2015-04-30 12:50:20 +00:00
|
|
|
|
2016-11-06 13:19:47 +00:00
|
|
|
log("played '", _name, "' ", ++cnt, " time(s)");
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ready()
|
|
|
|
{
|
|
|
|
start();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static int process_config(const char ***files)
|
|
|
|
{
|
|
|
|
enum { MAX_FILES = 16 };
|
|
|
|
|
|
|
|
static char file_mem[64][MAX_FILES];
|
|
|
|
static const char *file_p[MAX_FILES];
|
|
|
|
int cnt = 0;
|
|
|
|
|
|
|
|
Xml_node config_node = config()->xml_node();
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < config_node.num_sub_nodes(); ++i) {
|
|
|
|
|
|
|
|
if (!(i < MAX_FILES)) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("test supports max ", (int)MAX_FILES, " files. Skipping...");
|
2011-12-22 15:19:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Xml_node file_node = config_node.sub_node(i);
|
|
|
|
|
|
|
|
if (!config_node.has_type("config")) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
error("root node of config file is not a <config> tag");
|
2011-12-22 15:19:25 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (file_node.has_type("filename")) {
|
|
|
|
memcpy(file_mem[cnt], file_node.content_addr(), file_node.content_size());
|
|
|
|
file_p[cnt] = file_mem[cnt];
|
|
|
|
file_mem[cnt][file_node.content_size()] = '\0';
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*files = file_p;
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
log("--- Audio_out test ---");
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
const char *defaults[] = { "1.raw", "2.raw" };
|
|
|
|
const char **files = defaults;
|
|
|
|
int cnt = 2;
|
|
|
|
|
|
|
|
try {
|
|
|
|
cnt = process_config(&files);
|
|
|
|
}
|
|
|
|
catch (...) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
warning("couldn't get input files, failing back to defaults");
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Track *track[cnt];
|
2012-12-20 16:34:33 +00:00
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
for (int i = 0; i < cnt; ++i) {
|
2012-12-20 16:34:33 +00:00
|
|
|
track[i] = new (env()->heap()) Track(files[i]);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* start playback after constrution of all tracks */
|
|
|
|
for (int i = 0; i < cnt; i++)
|
|
|
|
track[i]->ready();
|
|
|
|
|
|
|
|
sleep_forever();
|
|
|
|
return 0;
|
|
|
|
}
|
2012-12-20 16:34:33 +00:00
|
|
|
|
|
|
|
|