PACKAGE_VERSION := @PACKAGE_VERSION@
M4 := @M4@
+LOPSUBGEN := @LOPSUBGEN@
executables := @executables@
NEWS
====
-
---------------------
current master branch
---------------------
- New sort order for the ls command: -s=h sorts the ls output by hash
value of the audio file.
+- autogen.sh now runs the test suite after a successful build.
- The contents of overview.pdf have been integrated into the user
manual.
- The doxygen source browser has been disabled temporarily. The
API reference is still online, though.
- Overhaul of the source code documentation.
+- The deprecated --full-path option of the ls command has been
+ removed. It was a no-op since 0.6.0.
+- The wma decoder has been cleaned up and its bitstream API made
+ more robust.
+- The image/lyrics ID status items of the current audio file are now
+ updated on changes. This affects para_gui, which used to report the
+ old value until EOF.
-------------------------------
0.6.0 (2017-04-28) "fuzzy flux"
spx_afh_init, flac_afh_init, opus_afh_init;
/** The list of all status items */
-const char *status_item_list[] = {STATUS_ITEM_ARRAY};
+const char *status_item_list[] = {STATUS_ITEMS};
/**
* The list of supported audio formats.
"%s: %s\n" /* year */
"%s: %s\n" /* album */
"%s: %s\n", /* comment */
- status_item_list[SI_BITRATE], afhi->bitrate,
- status_item_list[SI_FORMAT], audio_format_name(audio_format_num),
- status_item_list[SI_FREQUENCY], afhi->frequency,
- status_item_list[SI_CHANNELS], afhi->channels,
- status_item_list[SI_SECONDS_TOTAL], afhi->seconds_total,
- status_item_list[SI_CHUNK_TIME], (long unsigned)afhi->chunk_tv.tv_sec,
+ status_item_list[SI_bitrate], afhi->bitrate,
+ status_item_list[SI_format], audio_format_name(audio_format_num),
+ status_item_list[SI_frequency], afhi->frequency,
+ status_item_list[SI_channels], afhi->channels,
+ status_item_list[SI_seconds_total], afhi->seconds_total,
+ status_item_list[SI_chunk_time], (long unsigned)afhi->chunk_tv.tv_sec,
(long unsigned)afhi->chunk_tv.tv_usec,
- status_item_list[SI_NUM_CHUNKS], afhi->chunks_total,
- status_item_list[SI_MAX_CHUNK_SIZE], afhi->max_chunk_size,
- status_item_list[SI_TECHINFO], afhi->techinfo? afhi->techinfo : "",
- status_item_list[SI_ARTIST], afhi->tags.artist? afhi->tags.artist : "",
- status_item_list[SI_TITLE], afhi->tags.title? afhi->tags.title : "",
- status_item_list[SI_YEAR], afhi->tags.year? afhi->tags.year : "",
- status_item_list[SI_ALBUM], afhi->tags.album? afhi->tags.album : "",
- status_item_list[SI_COMMENT], afhi->tags.comment? afhi->tags.comment : ""
+ status_item_list[SI_num_chunks], afhi->chunks_total,
+ status_item_list[SI_max_chunk_size], afhi->max_chunk_size,
+ status_item_list[SI_techinfo], afhi->techinfo? afhi->techinfo : "",
+ status_item_list[SI_artist], afhi->tags.artist? afhi->tags.artist : "",
+ status_item_list[SI_title], afhi->tags.title? afhi->tags.title : "",
+ status_item_list[SI_year], afhi->tags.year? afhi->tags.year : "",
+ status_item_list[SI_album], afhi->tags.album? afhi->tags.album : "",
+ status_item_list[SI_comment], afhi->tags.comment? afhi->tags.comment : ""
);
}
ret = change_current_mood(arg + 2);
mode = PLAY_MODE_MOOD;
} else
- return -E_AFS_SYNTAX;
+ return -ERRNO_TO_PARA_ERROR(EINVAL);
if (ret < 0)
return ret;
}
strncpy(mmd->afs_mode_string, arg,
sizeof(mmd->afs_mode_string));
mmd->afs_mode_string[sizeof(mmd->afs_mode_string) - 1] = '\0';
+ mmd->events++;
mutex_unlock(mmd_mutex);
} else {
mutex_lock(mmd_mutex);
strcpy(mmd->afs_mode_string, "dummy");
+ mmd->events++;
mutex_unlock(mmd_mutex);
current_mop = NULL;
}
goto out;
/* ignore subsequent errors (but log them) */
para_printf(&aca->pbout, "could not activate %s\n", arg);
- if (current_mop) {
+ if (current_mop && strcmp(current_mop, arg) != 0) {
int ret2;
para_printf(&aca->pbout, "switching back to %s\n", current_mop);
ret2 = activate_mood_or_playlist(current_mop, &num_admissible);
static void init_admissible_files(const char *arg)
{
- if (activate_mood_or_playlist(arg, NULL) < 0)
+ int ret = activate_mood_or_playlist(arg, NULL);
+ if (ret < 0) {
+ assert(arg);
+ PARA_WARNING_LOG("could not activate %s: %s\n", arg,
+ para_strerror(-ret));
activate_mood_or_playlist(NULL, NULL); /* always successful */
+ }
}
static int setup_command_socket_or_die(void)
struct osl_object path_obj;
int ret = osl(osl_get_object(audio_file_table, row, AFTCOL_PATH,
&path_obj));
+
if (ret < 0)
- return ret;
- *path = path_obj.data;
- return 1;
+ *path = NULL;
+ else
+ *path = path_obj.data;
+ return ret;
}
/**
char *att_text;
int ret;
- WRITE_STATUS_ITEM(b, SI_ATTRIBUTES_BITMAP, "%s\n", att_bitmap);
+ WRITE_STATUS_ITEM(b, SI_attributes_bitmap, "%s\n", att_bitmap);
ret = get_attribute_text(&afsi->attributes, " ", &att_text);
if (ret < 0)
return ret;
- WRITE_STATUS_ITEM(b, SI_ATTRIBUTES_TXT, "%s\n", att_text);
+ WRITE_STATUS_ITEM(b, SI_attributes_txt, "%s\n", att_text);
free(att_text);
return ret;
}
{
char *lyrics_name;
- WRITE_STATUS_ITEM(b, SI_LYRICS_ID, "%u\n", afsi->lyrics_id);
+ WRITE_STATUS_ITEM(b, SI_lyrics_id, "%u\n", afsi->lyrics_id);
lyr_get_name_by_id(afsi->lyrics_id, &lyrics_name);
- WRITE_STATUS_ITEM(b, SI_LYRICS_NAME, "%s\n", lyrics_name?
+ WRITE_STATUS_ITEM(b, SI_lyrics_name, "%s\n", lyrics_name?
lyrics_name : "(none)");
}
{
char *image_name;
- WRITE_STATUS_ITEM(b, SI_IMAGE_ID, "%u\n", afsi->image_id);
+ WRITE_STATUS_ITEM(b, SI_image_id, "%u\n", afsi->image_id);
img_get_name_by_id(afsi->image_id, &image_name);
- WRITE_STATUS_ITEM(b, SI_IMAGE_NAME, "%s\n", image_name?
+ WRITE_STATUS_ITEM(b, SI_image_name, "%s\n", image_name?
image_name : "(none)");
}
char *val;
if (basename) {
- WRITE_STATUS_ITEM(b, SI_BASENAME, "%s\n", path);
+ WRITE_STATUS_ITEM(b, SI_basename, "%s\n", path);
return;
}
- WRITE_STATUS_ITEM(b, SI_PATH, "%s\n", path);
+ WRITE_STATUS_ITEM(b, SI_path, "%s\n", path);
val = para_basename(path);
- WRITE_STATUS_ITEM(b, SI_BASENAME, "%s\n", val? val : "");
+ WRITE_STATUS_ITEM(b, SI_basename, "%s\n", val? val : "");
val = para_dirname(path);
- WRITE_STATUS_ITEM(b, SI_DIRECTORY, "%s\n", val? val : "");
+ WRITE_STATUS_ITEM(b, SI_directory, "%s\n", val? val : "");
free(val);
}
}
write_filename_items(b, d->path, lls_opt_given(r_b));
if (lls_opt_given(r_a))
- WRITE_STATUS_ITEM(b, SI_SCORE, "%li\n", d->score);
+ WRITE_STATUS_ITEM(b, SI_score, "%li\n", d->score);
ret = write_attribute_items(b, att_buf, afsi);
if (ret < 0)
goto out;
write_image_items(b, afsi);
write_lyrics_items(b, afsi);
hash_to_asc(d->hash, asc_hash);
- WRITE_STATUS_ITEM(b, SI_HASH, "%s\n", asc_hash);
- WRITE_STATUS_ITEM(b, SI_BITRATE, "%dkbit/s\n", afhi->bitrate);
- WRITE_STATUS_ITEM(b, SI_FORMAT, "%s\n",
+ WRITE_STATUS_ITEM(b, SI_hash, "%s\n", asc_hash);
+ WRITE_STATUS_ITEM(b, SI_bitrate, "%dkbit/s\n", afhi->bitrate);
+ WRITE_STATUS_ITEM(b, SI_format, "%s\n",
audio_format_name(afsi->audio_format_id));
- WRITE_STATUS_ITEM(b, SI_FREQUENCY, "%dHz\n", afhi->frequency);
- WRITE_STATUS_ITEM(b, SI_CHANNELS, "%d\n", afhi->channels);
- WRITE_STATUS_ITEM(b, SI_DURATION, "%s\n", duration_buf);
- WRITE_STATUS_ITEM(b, SI_SECONDS_TOTAL, "%" PRIu32 "\n",
+ WRITE_STATUS_ITEM(b, SI_frequency, "%dHz\n", afhi->frequency);
+ WRITE_STATUS_ITEM(b, SI_channels, "%d\n", afhi->channels);
+ WRITE_STATUS_ITEM(b, SI_duration, "%s\n", duration_buf);
+ WRITE_STATUS_ITEM(b, SI_seconds_total, "%" PRIu32 "\n",
afhi->seconds_total);
- WRITE_STATUS_ITEM(b, SI_LAST_PLAYED, "%s\n", last_played_time);
- WRITE_STATUS_ITEM(b, SI_NUM_PLAYED, "%u\n", afsi->num_played);
- WRITE_STATUS_ITEM(b, SI_AMPLIFICATION, "%u\n", afsi->amp);
- WRITE_STATUS_ITEM(b, SI_CHUNK_TIME, "%lu\n", tv2ms(&afhi->chunk_tv));
- WRITE_STATUS_ITEM(b, SI_NUM_CHUNKS, "%" PRIu32 "\n",
+ WRITE_STATUS_ITEM(b, SI_last_played, "%s\n", last_played_time);
+ WRITE_STATUS_ITEM(b, SI_num_played, "%u\n", afsi->num_played);
+ WRITE_STATUS_ITEM(b, SI_amplification, "%u\n", afsi->amp);
+ WRITE_STATUS_ITEM(b, SI_chunk_time, "%lu\n", tv2ms(&afhi->chunk_tv));
+ WRITE_STATUS_ITEM(b, SI_num_chunks, "%" PRIu32 "\n",
afhi->chunks_total);
- WRITE_STATUS_ITEM(b, SI_MAX_CHUNK_SIZE, "%" PRIu32 "\n",
+ WRITE_STATUS_ITEM(b, SI_max_chunk_size, "%" PRIu32 "\n",
afhi->max_chunk_size);
- WRITE_STATUS_ITEM(b, SI_TECHINFO, "%s\n", afhi->techinfo);
- WRITE_STATUS_ITEM(b, SI_ARTIST, "%s\n", afhi->tags.artist);
- WRITE_STATUS_ITEM(b, SI_TITLE, "%s\n", afhi->tags.title);
- WRITE_STATUS_ITEM(b, SI_YEAR, "%s\n", afhi->tags.year);
- WRITE_STATUS_ITEM(b, SI_ALBUM, "%s\n", afhi->tags.album);
- WRITE_STATUS_ITEM(b, SI_COMMENT, "%s\n", afhi->tags.comment);
+ WRITE_STATUS_ITEM(b, SI_techinfo, "%s\n", afhi->techinfo);
+ WRITE_STATUS_ITEM(b, SI_artist, "%s\n", afhi->tags.artist);
+ WRITE_STATUS_ITEM(b, SI_title, "%s\n", afhi->tags.title);
+ WRITE_STATUS_ITEM(b, SI_year, "%s\n", afhi->tags.year);
+ WRITE_STATUS_ITEM(b, SI_album, "%s\n", afhi->tags.album);
+ WRITE_STATUS_ITEM(b, SI_comment, "%s\n", afhi->tags.comment);
if (opts->mode == LS_MODE_MBOX) {
struct osl_object lyrics_def;
lyr_get_def_by_id(afsi->lyrics_id, &lyrics_def);
ret = strftime(mtime_str, 29, "%b %d %Y", &mtime_tm);
assert(ret > 0); /* number of bytes placed in mtime_str */
out:
- WRITE_STATUS_ITEM(pb, SI_MTIME, "%s\n", mtime_str);
- WRITE_STATUS_ITEM(pb, SI_FILE_SIZE, "%ld\n", statbuf.st_size / 1024);
+ WRITE_STATUS_ITEM(pb, SI_mtime, "%s\n", mtime_str);
+ WRITE_STATUS_ITEM(pb, SI_file_size, "%ld\n", statbuf.st_size / 1024);
}
static int make_status_items(void)
time_t current_time;
int ret;
+ if (!status_item_ls_data.path) /* no audio file open */
+ return 0;
ret = lls_parse(ARRAY_SIZE(argv), argv, cmd, &opts.lpr, NULL);
assert(ret >= 0);
time(¤t_time);
return ret;
make_status_items();
return 1;
+ }
+ case BLOB_RENAME:
+ case BLOB_REMOVE:
+ case BLOB_ADD: {
+ /*
+ * These events are rare. We don't bother to check whether the
+ * current status items are affected and simply recreate them
+ * every time.
+ */
+ make_status_items();
} default:
return 0;
}
fn->private_data = pad;
fn->min_iqs = 2;
- if (!given && stat_item_values[SI_AMPLIFICATION])
- sscanf(stat_item_values[SI_AMPLIFICATION], "%u", &pad->amp);
+ if (!given && stat_item_values[SI_amplification])
+ sscanf(stat_item_values[SI_amplification], "%u", &pad->amp);
else
pad->amp = amp_arg;
PARA_INFO_LOG("amplification: %u (scaling factor: %1.2f)\n",
static void stat_completer(struct i9e_completion_info *ci,
struct i9e_completion_result *cr)
{
- char *sia[] = {STATUS_ITEM_ARRAY NULL};
+ char *sia[] = {STATUS_ITEMS NULL};
char *opts[] = {LSG_AUDIOD_CMD_STAT_OPTS, NULL};
if (ci->word_num <= 2 && ci->word && ci->word[0] == '-')
EMBRACE(.name = name, .context = rn));
ret = r->open(rn);
if (ret < 0) {
+ PARA_ERROR_LOG("could not open %s receiver\n", name);
btr_remove_node(&rn->btrn);
free(rn);
return ret;
{
long unsigned sec, usec;
- if (stat_task->clock_diff_count && itemnum != SI_CURRENT_TIME)
+ if (stat_task->clock_diff_count && itemnum != SI_current_time)
return 1;
free(stat_item_values[itemnum]);
stat_item_values[itemnum] = para_strdup(buf);
stat_client_write_item(itemnum);
switch (itemnum) {
- case SI_STATUS_FLAGS:
+ case SI_status_flags:
stat_task->vss_status = 0;
if (strchr(buf, 'N'))
stat_task->vss_status |= VSS_STATUS_FLAG_NEXT;
if (strchr(buf, 'P'))
stat_task->vss_status |= VSS_STATUS_FLAG_PLAYING;
break;
- case SI_OFFSET:
+ case SI_offset:
stat_task->offset_seconds = atoi(buf);
break;
- case SI_SECONDS_TOTAL:
+ case SI_seconds_total:
stat_task->length_seconds = atoi(buf);
break;
- case SI_STREAM_START:
+ case SI_stream_start:
if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) {
stat_task->server_stream_start.tv_sec = sec;
stat_task->server_stream_start.tv_usec = usec;
}
break;
- case SI_CURRENT_TIME:
+ case SI_current_time:
if (sscanf(buf, "%lu.%lu", &sec, &usec) == 2) {
struct timeval tv = {sec, usec};
compute_time_diff(&tv);
}
break;
- case SI_FORMAT:
+ case SI_format:
stat_task->current_audio_format_num
= get_audio_format_num(buf);
}
client_open(argc, argv, &st->ct, NULL, NULL, st->btrn, s);
set_stat_task_restart_barrier(5);
}
- free(stat_item_values[SI_BASENAME]);
- stat_item_values[SI_BASENAME] = para_strdup(
+ free(stat_item_values[SI_basename]);
+ stat_item_values[SI_basename] = para_strdup(
"no connection to para_server");
- stat_client_write_item(SI_BASENAME);
+ stat_client_write_item(SI_basename);
st->last_status_read = *now;
out:
start_stop_decoders();
static int num_clients;
/** The list of all status items used by para_{server,audiod,gui}. */
-const char *status_item_list[] = {STATUS_ITEM_ARRAY};
+const char *status_item_list[] = {STATUS_ITEMS};
static void dump_stat_client_list(void)
{
{
char *old, *new;
- old = stat_item_values[SI_PLAY_TIME];
+ old = stat_item_values[SI_play_time];
new = get_time_string();
if (new) {
if (force || !old || strcmp(old, new)) {
free(old);
- stat_item_values[SI_PLAY_TIME] = new;
- stat_client_write_item(SI_PLAY_TIME);
+ stat_item_values[SI_play_time] = new;
+ stat_client_write_item(SI_play_time);
} else
free(new);
}
new = daemon_get_uptime_str(now);
- old = stat_item_values[SI_AUDIOD_UPTIME];
+ old = stat_item_values[SI_audiod_uptime];
if (force || !old || strcmp(old, new)) {
free(old);
- stat_item_values[SI_AUDIOD_UPTIME] = new;
- stat_client_write_item(SI_AUDIOD_UPTIME);
+ stat_item_values[SI_audiod_uptime] = new;
+ stat_client_write_item(SI_audiod_uptime);
} else
free(new);
- old = stat_item_values[SI_AUDIOD_STATUS];
+ old = stat_item_values[SI_audiod_status];
new = audiod_status_string();
if (force || !old || strcmp(old, new)) {
free(old);
- stat_item_values[SI_AUDIOD_STATUS] = new;
- stat_client_write_item(SI_AUDIOD_STATUS);
+ stat_item_values[SI_audiod_status] = new;
+ stat_client_write_item(SI_audiod_status);
} else
free(new);
- old = stat_item_values[SI_DECODER_FLAGS];
+ old = stat_item_values[SI_decoder_flags];
new = audiod_get_decoder_flags();
if (force || !old || strcmp(old, new)) {
free(old);
- stat_item_values[SI_DECODER_FLAGS] = new;
- stat_client_write_item(SI_DECODER_FLAGS);
+ stat_item_values[SI_decoder_flags] = new;
+ stat_client_write_item(SI_decoder_flags);
} else
free(new);
}
./configure $@ > /dev/null
echo compiling...
make clean > /dev/null 2>&1
-make -j $n > /dev/null
+make -j $n > /dev/null && make check
if (vlc->table_size > vlc->table_allocated) {
vlc->table_allocated += (1 << vlc->bits);
vlc->table = para_realloc(vlc->table,
- sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
+ sizeof(int16_t) * 2 * vlc->table_allocated);
}
}
{
int i, j, k, n, table_size, table_index, nb, n1, idx;
uint32_t code;
- VLC_TYPE(*table)[2];
+ int16_t (*table)[2];
table_size = 1 << table_nb_bits;
table_index = vlc->table_size;
* Parse a vlc code.
*
* \param gbc The getbit context structure.
- * \param table The vlc tables to use.
- * \param bits The number of bits which will be read at once.
- *
- * The \a bits parameter must be identical to the \a nb_bits value supplied to
- * \ref init_vlc().
+ * \param vlc The vlc tables to use.
*
* \return The vlc code.
*/
-int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits)
+int get_vlc(struct getbit_context *gbc, const struct vlc *vlc)
{
int n, idx, nb_bits, code;
- idx = show_bits(gbc, bits);
- code = table[idx][0];
- n = table[idx][1];
+ idx = show_bits(gbc, vlc->bits);
+ code = vlc->table[idx][0];
+ n = vlc->table[idx][1];
if (n < 0) {
- skip_bits(gbc, bits);
+ skip_bits(gbc, vlc->bits);
nb_bits = -n;
idx = show_bits(gbc, nb_bits) + code;
- code = table[idx][0];
- n = table[idx][1];
+ code = vlc->table[idx][0];
+ n = vlc->table[idx][1];
if (n < 0) {
skip_bits(gbc, nb_bits);
nb_bits = -n;
idx = show_bits(gbc, nb_bits) + code;
- code = table[idx][0];
- n = table[idx][1];
+ code = vlc->table[idx][0];
+ n = vlc->table[idx][1];
}
}
skip_bits(gbc, n);
struct getbit_context {
/** Start of the internal buffer. */
const uint8_t *buffer;
- /** End of the internal buffer. */
- const uint8_t *buffer_end;
+ /** Length of buffer in bits (always a multiple of 8). */
+ uint32_t num_bits;
/** Bit counter. */
int index;
};
-#define VLC_TYPE int16_t
-
/** A variable length code table. */
struct vlc {
/** Number of bits of the table. */
int bits;
/** The code and the bits table. */
- VLC_TYPE(*table)[2];
+ int16_t (*table)[2];
/** The size of the table. */
int table_size;
/** Amount of memory allocated so far. */
static inline uint32_t show_bits(struct getbit_context *gbc, int num)
{
int idx = gbc->index;
- const char *p = (const char *)gbc->buffer + (idx >> 3);
- uint32_t x = read_u32_be(p);
+ const char *p;
+ uint32_t x;
+
+ assert(idx + num <= gbc->num_bits);
+ p = (const char *)gbc->buffer + (idx >> 3);
+ x = read_u32_be(p);
return (x << (idx & 7)) >> (32 - num);
}
static inline void skip_bits(struct getbit_context *gbc, int n)
{
+ assert(gbc->index + n <= gbc->num_bits);
gbc->index += n;
}
static inline unsigned int get_bits(struct getbit_context *gbc, int n)
{
- unsigned int ret = show_bits(gbc, n);
+ unsigned int ret = show_bits(gbc, n); /* checks n */
skip_bits(gbc, n);
return ret;
}
/* This is rather hot, we can do better than get_bits(gbc, 1). */
static inline unsigned int get_bit(struct getbit_context *gbc)
{
- int idx = gbc->index++;
- uint8_t tmp = gbc->buffer[idx >> 3], mask = 1 << (7 - (idx & 7));
+ int idx;
+ uint8_t tmp, mask;
+
+ assert(gbc->index < gbc->num_bits);
+ idx = gbc->index++;
+ tmp = gbc->buffer[idx >> 3];
+ mask = 1 << (7 - (idx & 7));
return !!(tmp & mask);
}
const uint8_t *buffer, int size)
{
gbc->buffer = buffer;
- gbc->buffer_end = buffer + size;
+ gbc->num_bits = size * 8;
gbc->index = 0;
}
void init_vlc(struct vlc *vlc, int nb_bits, int nb_codes, const void *bits,
const void *codes, int codes_size);
void free_vlc(struct vlc *vlc);
-int get_vlc(struct getbit_context *gbc, VLC_TYPE(*table)[2], int bits);
+int get_vlc(struct getbit_context *gbc, const struct vlc *vlc);
* clang is not smart enough to prove this and complains nevertheless.
* Casting the return value to void silences clang.
*/
- (void)WRITE_STATUS_ITEM(&b, SI_STATUS, "%s\n", status);
- (void)WRITE_STATUS_ITEM(&b, SI_STATUS_FLAGS, "%s\n", flags);
- (void)WRITE_STATUS_ITEM(&b, SI_OFFSET, "%li\n", offset);
- (void)WRITE_STATUS_ITEM(&b, SI_AFS_MODE, "%s\n", mmd->afs_mode_string);
- (void)WRITE_STATUS_ITEM(&b, SI_STREAM_START, "%lu.%lu\n",
+ (void)WRITE_STATUS_ITEM(&b, SI_status, "%s\n", status);
+ (void)WRITE_STATUS_ITEM(&b, SI_status_flags, "%s\n", flags);
+ (void)WRITE_STATUS_ITEM(&b, SI_offset, "%li\n", offset);
+ (void)WRITE_STATUS_ITEM(&b, SI_afs_mode, "%s\n", mmd->afs_mode_string);
+ (void)WRITE_STATUS_ITEM(&b, SI_stream_start, "%lu.%lu\n",
(long unsigned)nmmd->stream_start.tv_sec,
(long unsigned)nmmd->stream_start.tv_usec);
- (void)WRITE_STATUS_ITEM(&b, SI_CURRENT_TIME, "%lu.%lu\n",
+ (void)WRITE_STATUS_ITEM(&b, SI_current_time, "%lu.%lu\n",
(long unsigned)current_time.tv_sec,
(long unsigned)current_time.tv_usec);
free(flags);
struct lls_parse_result *lpr, struct sender_command_data *scd)
{
int i, ret;
- const char *subcmds[] = {SENDER_SUBCOMMANDS};
+ const char * const subcmds[] = {SENDER_SUBCOMMANDS};
const char *arg;
char *errctx;
unsigned num_inputs = lls_num_inputs(lpr);
return -E_COMMAND_SYNTAX;
scd->sender_num = i;
arg = lls_input(1, lpr);
- for (i = 0; subcmds[i]; i++)
+ for (i = 0; i < NUM_SENDER_CMDS; i++)
if (!strcmp(subcmds[i], arg))
break;
- if (!subcmds[i])
+ if (i == NUM_SENDER_CMDS)
return -E_COMMAND_SYNTAX;
scd->cmd_num = i;
if (!senders[scd->sender_num].client_cmds[scd->cmd_num])
/** These status items are cleared if no audio file is currently open. */
#define EMPTY_STATUS_ITEMS \
- ITEM(PATH) \
- ITEM(DIRECTORY) \
- ITEM(BASENAME) \
- ITEM(SCORE) \
- ITEM(ATTRIBUTES_BITMAP) \
- ITEM(ATTRIBUTES_TXT) \
- ITEM(HASH) \
- ITEM(IMAGE_ID) \
- ITEM(IMAGE_NAME) \
- ITEM(LYRICS_ID) \
- ITEM(LYRICS_NAME) \
- ITEM(BITRATE) \
- ITEM(FORMAT) \
- ITEM(FREQUENCY) \
- ITEM(CHANNELS) \
- ITEM(DURATION) \
- ITEM(SECONDS_TOTAL) \
- ITEM(NUM_PLAYED) \
- ITEM(LAST_PLAYED) \
- ITEM(TECHINFO) \
- ITEM(ARTIST) \
- ITEM(TITLE) \
- ITEM(YEAR) \
- ITEM(ALBUM) \
- ITEM(COMMENT) \
- ITEM(MTIME) \
- ITEM(FILE_SIZE) \
- ITEM(CHUNK_TIME) \
- ITEM(NUM_CHUNKS) \
- ITEM(AMPLIFICATION) \
+ ITEM(path) \
+ ITEM(directory) \
+ ITEM(basename) \
+ ITEM(score) \
+ ITEM(attributes_bitmap) \
+ ITEM(attributes_txt) \
+ ITEM(hash) \
+ ITEM(image_id) \
+ ITEM(image_name) \
+ ITEM(lyrics_id) \
+ ITEM(lyrics_name) \
+ ITEM(bitrate) \
+ ITEM(format) \
+ ITEM(frequency) \
+ ITEM(channels) \
+ ITEM(duration) \
+ ITEM(seconds_total) \
+ ITEM(num_played) \
+ ITEM(last_played) \
+ ITEM(techinfo) \
+ ITEM(artist) \
+ ITEM(title) \
+ ITEM(year) \
+ ITEM(album) \
+ ITEM(comment) \
+ ITEM(mtime) \
+ ITEM(file_size) \
+ ITEM(chunk_time) \
+ ITEM(num_chunks) \
+ ITEM(amplification) \
-/**
- * Write a list of audio-file related status items with empty values.
- *
- * This is used by vss when currently no audio file is open.
+/*
+ * Create a set of audio-file related status items with empty values. These are
+ * written to stat clients when no audio file is open.
*/
static unsigned empty_status_items(bool parser_friendly, char **result)
{
unsigned char challenge_hash[HASH_SIZE];
char *command = NULL, *buf = para_malloc(HANDSHAKE_BUFSIZE) /* must be on the heap */;
size_t numbytes;
- struct command_context cc_struct = {.peer = peername}, *cc = &cc_struct;
+ struct command_context cc_struct = {.u = NULL}, *cc = &cc_struct;
struct iovec iov;
struct connection_features cf;
/** Per connection data available to command handlers. */
struct command_context {
- /** Network address of the peer. */
- const char *peer;
/** The paraslash user that executes this command. */
struct user *u;
/** File descriptor and crypto keys. */
test -z "$M4" && AC_MSG_ERROR(
[The m4 macro processor is required to build this package])
-AC_PATH_PROG([lopsubgen], [lopsubgen])
-test -z "$lopsubgen" && AC_MSG_ERROR(
- [lopsubgen is required to build this package])
-
AC_PROG_CC
AC_PROG_CPP
LIB_SUBST_FLAGS(osl)
UNSTASH_FLAGS
######################################################################## lopsub
+HAVE_LOPSUB=yes
+AC_PATH_PROG([LOPSUBGEN], [lopsubgen])
+test -z "$LOPSUBGEN" && HAVE_LOPSUB=no
STASH_FLAGS
LIB_ARG_WITH([lopsub], [-llopsub])
-HAVE_LOPSUB=yes
AC_CHECK_HEADER(lopsub.h, [], [HAVE_LOPSUB=no])
AC_CHECK_LIB([lopsub], [lls_merge], [], [HAVE_LOPSUB=no])
if test $HAVE_LOPSUB = no; then AC_MSG_ERROR([
AC_MSG_RESULT($msg)
UNSTASH_FLAGS
########################################################################### ucred
-AC_MSG_CHECKING(for struct ucred)
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+AC_CHECK_TYPE([struct ucred], [
+ AC_DEFINE(HAVE_UCRED, 1, define to 1 you have struct ucred)
+], [], [
#include <sys/types.h>
#include <sys/socket.h>
-]], [[
- struct ucred sucred; sucred.pid=0;
-]])],[have_ucred=yes],[have_ucred=no])
-AC_MSG_RESULT($have_ucred)
-if test ${have_ucred} = yes; then
- AC_DEFINE(HAVE_UCRED, 1, define to 1 you have struct ucred)
-fi
+])
########################################################################### curses
STASH_FLAGS
LIB_ARG_WITH([curses], [])
LIB_SUBST_FLAGS(curses)
UNSTASH_FLAGS
########################################################################### ip_mreqn
-AC_MSG_CHECKING(for struct ip_mreqn (UDPv4 multicast))
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+AC_CHECK_TYPE([struct ip_mreqn], [
+ AC_DEFINE(HAVE_IP_MREQN, 1, define to 1 if you have struct ip_mreqn)
+], [], [
#include <netdb.h>
#include <net/if.h>
-]], [[
- struct ip_mreqn mn;
- mn.imr_ifindex = 0;
-]])],[have_ip_mreqn=yes],[have_ip_mreqn=no])
-AC_MSG_RESULT($have_ip_mreqn)
-if test ${have_ip_mreqn} = yes; then
- AC_DEFINE(HAVE_IP_MREQN, 1, define to 1 if you have struct ip_mreqn)
-fi
+])
########################################################################### ogg
STASH_FLAGS
LIB_ARG_WITH([ogg], [-logg])
fi
audioc_objs="$audioc_errlist_objs"
AC_SUBST(audioc_objs, add_dot_o($audioc_objs))
-################################################################## status items
-
-status_items="basename status num_played mtime bitrate frequency file_size
-status_flags format score techinfo afs_mode
-attributes_txt decoder_flags audiod_status play_time attributes_bitmap
-offset seconds_total stream_start current_time audiod_uptime image_id
-lyrics_id duration directory lyrics_name image_name path hash channels
-last_played num_chunks chunk_time amplification artist title year album
-comment max_chunk_size"
-
-result=
-for i in $status_items; do
- result="$result SI_$(echo $i | tr 'a-z' 'A-Z'), "
-done
-AC_DEFINE_UNQUOTED(STATUS_ITEM_ENUM, [$result],
- [enum of all status items])
-
-result=
-for i in $status_items; do
- result="$result \"$i\", "
-done
-AC_DEFINE_UNQUOTED(STATUS_ITEM_ARRAY, [$result],
- [char * array of all status items])
AC_DEFINE_UNQUOTED(AUDIO_FORMAT_HANDLERS, "$audio_format_handlers",
[formats supported by para_server and para_afh])
-
AC_SUBST(executables)
AC_OUTPUT
PARA_ERROR(AFS_SHORT_READ, "short read from afs socket"), \
PARA_ERROR(AFS_SIGNAL, "afs caught deadly signal"), \
PARA_ERROR(AFS_SOCKET, "afs socket not writable"), \
- PARA_ERROR(AFS_SYNTAX, "afs syntax error"), \
PARA_ERROR(AFT_SYNTAX, "audio file table syntax error"), \
PARA_ERROR(ALSA, "alsa error"), \
PARA_ERROR(ALSA_MIX_GET_VAL, "could not read control element state"), \
return ret;
}
-/**
- * A wrapper for fchdir().
- *
- * \param fd An open file descriptor.
- *
- * \return Standard.
- */
-static int para_fchdir(int fd)
-{
- if (fchdir(fd) < 0)
- return -ERRNO_TO_PARA_ERROR(errno);
- return 1;
-}
-
/**
* A wrapper for mkdir(2).
*
{
DIR *dir;
struct dirent *entry;
- int cwd_fd, ret2, ret = para_opendir(dirname, &dir, &cwd_fd);
+ int cwd_fd, ret = para_opendir(dirname, &dir, &cwd_fd);
if (ret < 0)
return ret == -ERRNO_TO_PARA_ERROR(EACCES)? 1 : ret;
ret = 1;
out:
closedir(dir);
- ret2 = para_fchdir(cwd_fd);
- if (ret2 < 0 && ret >= 0)
- ret = ret2;
+ if (fchdir(cwd_fd) < 0 && ret >= 0)
+ ret = -ERRNO_TO_PARA_ERROR(errno);
close(cwd_fd);
return ret;
}
#define OPT_UINT32_VAL(_name) (lls_uint32_val(0, OPT_RESULT(_name)))
/** The list of all status items used by para_{server,audiod,gui}. */
-const char *status_item_list[] = {STATUS_ITEM_ARRAY};
+const char *status_item_list[] = {STATUS_ITEMS};
/**
* Dummy version which only contains NULL pointers.
#include "string.h"
/** Iterate over all filters. */
-#define FOR_EACH_FILTER(j) for (j = 1; lls_cmd(j, filter_cmd_suite); j++)
+#define FOR_EACH_FILTER(j) for (j = 1; FILTER_CMD(j); j++)
/**
* Obtain a reference to a filter structure.
if (buf && buf[0])
goto dup;
switch (item_num) {
- case SI_ARTIST:
+ case SI_artist:
*c = para_strdup("(artist tag not set)");
goto print;
- case SI_TITLE:
+ case SI_title:
*c = para_strdup("(title tag not set)");
goto print;
- case SI_YEAR:
+ case SI_year:
*c = para_strdup("????");
goto print;
- case SI_ALBUM:
+ case SI_album:
*c = para_strdup("(album tag not set)");
goto print;
- case SI_COMMENT:
+ case SI_comment:
*c = para_strdup("(comment tag not set)");
goto print;
}
close(st->fd);
st->fd = -1;
clear_all_items();
- free(stat_content[SI_BASENAME]);
- stat_content[SI_BASENAME] =
+ free(stat_content[SI_basename]);
+ stat_content[SI_basename] =
para_strdup("stat command terminated!?");
print_all_items();
return 0;
t->dflt.bg = COLOR_BLUE;
t->sep_char = '*';
- d[SI_BASENAME].prefix = "";
- d[SI_BASENAME].postfix = "";
- d[SI_BASENAME].color.fg = COLOR_WHITE;
- d[SI_BASENAME].color.bg = COLOR_BLUE;
- d[SI_BASENAME].align = CENTER;
- d[SI_BASENAME].x = 0;
- d[SI_BASENAME].y = 7;
- d[SI_BASENAME].len = 100;
-
- d[SI_STATUS].prefix = "para_server: ";
- d[SI_STATUS].postfix = "";
- d[SI_STATUS].color.fg = COLOR_WHITE;
- d[SI_STATUS].color.bg = COLOR_BLUE;
- d[SI_STATUS].align = CENTER;
- d[SI_STATUS].x = 0;
- d[SI_STATUS].y = 60;
- d[SI_STATUS].len = 50;
-
- d[SI_AUDIOD_STATUS].prefix = "para_audiod: ";
- d[SI_AUDIOD_STATUS].postfix = "";
- d[SI_AUDIOD_STATUS].color.fg = COLOR_WHITE;
- d[SI_AUDIOD_STATUS].color.bg = COLOR_BLUE;
- d[SI_AUDIOD_STATUS].align = CENTER;
- d[SI_AUDIOD_STATUS].x = 50;
- d[SI_AUDIOD_STATUS].y = 60;
- d[SI_AUDIOD_STATUS].len = 50;
+ d[SI_basename].prefix = "";
+ d[SI_basename].postfix = "";
+ d[SI_basename].color.fg = COLOR_WHITE;
+ d[SI_basename].color.bg = COLOR_BLUE;
+ d[SI_basename].align = CENTER;
+ d[SI_basename].x = 0;
+ d[SI_basename].y = 7;
+ d[SI_basename].len = 100;
+
+ d[SI_status].prefix = "para_server: ";
+ d[SI_status].postfix = "";
+ d[SI_status].color.fg = COLOR_WHITE;
+ d[SI_status].color.bg = COLOR_BLUE;
+ d[SI_status].align = CENTER;
+ d[SI_status].x = 0;
+ d[SI_status].y = 60;
+ d[SI_status].len = 50;
+
+ d[SI_audiod_status].prefix = "para_audiod: ";
+ d[SI_audiod_status].postfix = "";
+ d[SI_audiod_status].color.fg = COLOR_WHITE;
+ d[SI_audiod_status].color.bg = COLOR_BLUE;
+ d[SI_audiod_status].align = CENTER;
+ d[SI_audiod_status].x = 50;
+ d[SI_audiod_status].y = 60;
+ d[SI_audiod_status].len = 50;
}
t->dflt.fg = COLOR_MAGENTA;
- d[SI_PLAY_TIME].prefix = "";
- d[SI_PLAY_TIME].postfix = "";
- d[SI_PLAY_TIME].color.fg = COLOR_CYAN;
- d[SI_PLAY_TIME].color.bg = COLOR_BLACK;
- d[SI_PLAY_TIME].align = CENTER;
- d[SI_PLAY_TIME].x = 0;
- d[SI_PLAY_TIME].y = 7;
- d[SI_PLAY_TIME].len = 35;
-
- d[SI_BASENAME].prefix = "";
- d[SI_BASENAME].postfix = "";
- d[SI_BASENAME].color.fg = COLOR_CYAN;
- d[SI_BASENAME].color.bg = COLOR_BLACK;
- d[SI_BASENAME].align = LEFT;
- d[SI_BASENAME].x = 35;
- d[SI_BASENAME].y = 7;
- d[SI_BASENAME].len = 65;
-
- d[SI_STATUS].prefix = "";
- d[SI_STATUS].postfix = " ";
- d[SI_STATUS].color.fg = COLOR_RED;
- d[SI_STATUS].color.bg = COLOR_BLACK;
- d[SI_STATUS].align = RIGHT;
- d[SI_STATUS].x = 0;
- d[SI_STATUS].y = 17;
- d[SI_STATUS].len = 11;
-
- d[SI_STATUS_FLAGS].prefix = "(";
- d[SI_STATUS_FLAGS].postfix = ")";
- d[SI_STATUS_FLAGS].color.fg = COLOR_RED;
- d[SI_STATUS_FLAGS].color.bg = COLOR_BLACK;
- d[SI_STATUS_FLAGS].align = LEFT;
- d[SI_STATUS_FLAGS].x = 11;
- d[SI_STATUS_FLAGS].y = 17;
- d[SI_STATUS_FLAGS].len = 10;
-
- d[SI_IMAGE_ID].prefix = "img: ";
- d[SI_IMAGE_ID].postfix = "";
- d[SI_IMAGE_ID].color.fg = COLOR_RED;
- d[SI_IMAGE_ID].color.bg = COLOR_BLACK;
- d[SI_IMAGE_ID].align = CENTER;
- d[SI_IMAGE_ID].x = 21;
- d[SI_IMAGE_ID].y = 17;
- d[SI_IMAGE_ID].len = 10;
-
- d[SI_LYRICS_ID].prefix = "lyr: ";
- d[SI_LYRICS_ID].postfix = "";
- d[SI_LYRICS_ID].color.fg = COLOR_RED;
- d[SI_LYRICS_ID].color.bg = COLOR_BLACK;
- d[SI_LYRICS_ID].align = CENTER;
- d[SI_LYRICS_ID].x = 31;
- d[SI_LYRICS_ID].y = 17;
- d[SI_LYRICS_ID].len = 11;
-
- d[SI_FORMAT].prefix = "format: ";
- d[SI_FORMAT].postfix = "";
- d[SI_FORMAT].color.fg = COLOR_RED;
- d[SI_FORMAT].color.bg = COLOR_BLACK;
- d[SI_FORMAT].align = CENTER;
- d[SI_FORMAT].x = 42;
- d[SI_FORMAT].y = 17;
- d[SI_FORMAT].len = 18;
-
- d[SI_NUM_PLAYED].prefix = "#";
- d[SI_NUM_PLAYED].postfix = "";
- d[SI_NUM_PLAYED].color.fg = COLOR_RED;
- d[SI_NUM_PLAYED].color.bg = COLOR_BLACK;
- d[SI_NUM_PLAYED].align = LEFT;
- d[SI_NUM_PLAYED].x = 60;
- d[SI_NUM_PLAYED].y = 17;
- d[SI_NUM_PLAYED].len = 5;
-
- d[SI_BITRATE].prefix = "";
- d[SI_BITRATE].postfix = "";
- d[SI_BITRATE].color.fg = COLOR_RED;
- d[SI_BITRATE].color.bg = COLOR_BLACK;
- d[SI_BITRATE].align = CENTER;
- d[SI_BITRATE].x = 65;
- d[SI_BITRATE].y = 17;
- d[SI_BITRATE].len = 13;
-
- d[SI_FREQUENCY].prefix = "";
- d[SI_FREQUENCY].postfix = "";
- d[SI_FREQUENCY].color.fg = COLOR_RED;
- d[SI_FREQUENCY].color.bg = COLOR_BLACK;
- d[SI_FREQUENCY].align = CENTER;
- d[SI_FREQUENCY].x = 78;
- d[SI_FREQUENCY].y = 17;
- d[SI_FREQUENCY].len = 10;
-
- d[SI_SCORE].prefix = "sc: ";
- d[SI_SCORE].postfix = "";
- d[SI_SCORE].color.fg = COLOR_RED;
- d[SI_SCORE].color.bg = COLOR_BLACK;
- d[SI_SCORE].align = CENTER;
- d[SI_SCORE].x = 88;
- d[SI_SCORE].y = 17;
- d[SI_SCORE].len = 10;
-
- d[SI_AUDIOD_STATUS].prefix = "";
- d[SI_AUDIOD_STATUS].postfix = "";
- d[SI_AUDIOD_STATUS].color.fg = COLOR_MAGENTA;
- d[SI_AUDIOD_STATUS].color.bg = COLOR_BLACK;
- d[SI_AUDIOD_STATUS].align = CENTER;
- d[SI_AUDIOD_STATUS].x = 0;
- d[SI_AUDIOD_STATUS].y = 27;
- d[SI_AUDIOD_STATUS].len = 5;
-
- d[SI_DECODER_FLAGS].prefix = "[";
- d[SI_DECODER_FLAGS].postfix = "]";
- d[SI_DECODER_FLAGS].color.fg = COLOR_MAGENTA;
- d[SI_DECODER_FLAGS].color.bg = COLOR_BLACK;
- d[SI_DECODER_FLAGS].align = CENTER;
- d[SI_DECODER_FLAGS].x = 5;
- d[SI_DECODER_FLAGS].y = 27;
- d[SI_DECODER_FLAGS].len = 10;
-
- d[SI_MTIME].prefix = "mod: ";
- d[SI_MTIME].postfix = "";
- d[SI_MTIME].color.fg = COLOR_MAGENTA;
- d[SI_MTIME].color.bg = COLOR_BLACK;
- d[SI_MTIME].align = CENTER;
- d[SI_MTIME].x = 15;
- d[SI_MTIME].y = 27;
- d[SI_MTIME].len = 22;
-
- d[SI_FILE_SIZE].prefix = "";
- d[SI_FILE_SIZE].postfix = "kb";
- d[SI_FILE_SIZE].color.fg = COLOR_MAGENTA;
- d[SI_FILE_SIZE].color.bg = COLOR_BLACK;
- d[SI_FILE_SIZE].align = CENTER;
- d[SI_FILE_SIZE].x = 37;
- d[SI_FILE_SIZE].y = 27;
- d[SI_FILE_SIZE].len = 10;
-
- d[SI_CHANNELS].prefix = "";
- d[SI_CHANNELS].postfix = "ch";
- d[SI_CHANNELS].color.fg = COLOR_MAGENTA;
- d[SI_CHANNELS].color.bg = COLOR_BLACK;
- d[SI_CHANNELS].align = CENTER;
- d[SI_CHANNELS].x = 47;
- d[SI_CHANNELS].y = 27;
- d[SI_CHANNELS].len = 5;
-
- d[SI_LAST_PLAYED].prefix = "lp: ";
- d[SI_LAST_PLAYED].postfix = "";
- d[SI_LAST_PLAYED].color.fg = COLOR_MAGENTA;
- d[SI_LAST_PLAYED].color.bg = COLOR_BLACK;
- d[SI_LAST_PLAYED].align = CENTER;
- d[SI_LAST_PLAYED].x = 52;
- d[SI_LAST_PLAYED].y = 27;
- d[SI_LAST_PLAYED].len = 21;
-
- d[SI_NUM_CHUNKS].prefix = "";
- d[SI_NUM_CHUNKS].postfix = "x";
- d[SI_NUM_CHUNKS].color.fg = COLOR_MAGENTA;
- d[SI_NUM_CHUNKS].color.bg = COLOR_BLACK;
- d[SI_NUM_CHUNKS].align = RIGHT;
- d[SI_NUM_CHUNKS].x = 73;
- d[SI_NUM_CHUNKS].y = 27;
- d[SI_NUM_CHUNKS].len = 11;
-
- d[SI_CHUNK_TIME].prefix = "";
- d[SI_CHUNK_TIME].postfix = "ms";
- d[SI_CHUNK_TIME].color.fg = COLOR_MAGENTA;
- d[SI_CHUNK_TIME].color.bg = COLOR_BLACK;
- d[SI_CHUNK_TIME].align = LEFT;
- d[SI_CHUNK_TIME].x = 84;
- d[SI_CHUNK_TIME].y = 27;
- d[SI_CHUNK_TIME].len = 8;
-
- d[SI_AMPLIFICATION].prefix = "amp:";
- d[SI_AMPLIFICATION].postfix = "";
- d[SI_AMPLIFICATION].color.fg = COLOR_MAGENTA;
- d[SI_AMPLIFICATION].color.bg = COLOR_BLACK;
- d[SI_AMPLIFICATION].align = RIGHT;
- d[SI_AMPLIFICATION].x = 92;
- d[SI_AMPLIFICATION].y = 27;
- d[SI_AMPLIFICATION].len = 8;
-
- d[SI_TECHINFO].prefix = "";
- d[SI_TECHINFO].postfix = "";
- d[SI_TECHINFO].color.fg = COLOR_GREEN;
- d[SI_TECHINFO].color.bg = COLOR_BLACK;
- d[SI_TECHINFO].align = CENTER;
- d[SI_TECHINFO].x = 0;
- d[SI_TECHINFO].y = 43;
- d[SI_TECHINFO].len = 100;
-
- d[SI_TITLE].prefix = "";
- d[SI_TITLE].postfix = ",";
- d[SI_TITLE].color.fg = COLOR_GREEN;
- d[SI_TITLE].color.bg = COLOR_BLACK;
- d[SI_TITLE].align = RIGHT;
- d[SI_TITLE].x = 0;
- d[SI_TITLE].y = 53;
- d[SI_TITLE].len = 45;
-
- d[SI_ARTIST].prefix = " by ";
- d[SI_ARTIST].postfix = "";
- d[SI_ARTIST].color.fg = COLOR_GREEN;
- d[SI_ARTIST].color.bg = COLOR_BLACK;
- d[SI_ARTIST].align = LEFT;
- d[SI_ARTIST].x = 45;
- d[SI_ARTIST].y = 53;
- d[SI_ARTIST].len = 45;
-
- d[SI_YEAR].prefix = "(";
- d[SI_YEAR].postfix = ")";
- d[SI_YEAR].color.fg = COLOR_GREEN;
- d[SI_YEAR].color.bg = COLOR_BLACK;
- d[SI_YEAR].align = RIGHT;
- d[SI_YEAR].x = 90;
- d[SI_YEAR].y = 53;
- d[SI_YEAR].len = 10;
-
- d[SI_ALBUM].prefix = "A: ";
- d[SI_ALBUM].postfix = ",";
- d[SI_ALBUM].color.fg = COLOR_GREEN;
- d[SI_ALBUM].color.bg = COLOR_BLACK;
- d[SI_ALBUM].align = RIGHT;
- d[SI_ALBUM].x = 0;
- d[SI_ALBUM].y = 63;
- d[SI_ALBUM].len = 50;
-
- d[SI_COMMENT].prefix = " C: ";
- d[SI_COMMENT].postfix = "";
- d[SI_COMMENT].color.fg = COLOR_GREEN;
- d[SI_COMMENT].color.bg = COLOR_BLACK;
- d[SI_COMMENT].align = LEFT;
- d[SI_COMMENT].x = 50;
- d[SI_COMMENT].y = 63;
- d[SI_COMMENT].len = 50;
-
- d[SI_AFS_MODE].prefix = "";
- d[SI_AFS_MODE].postfix = "";
- d[SI_AFS_MODE].color.fg = COLOR_YELLOW;
- d[SI_AFS_MODE].color.bg = COLOR_BLACK;
- d[SI_AFS_MODE].align = CENTER;
- d[SI_AFS_MODE].x = 0;
- d[SI_AFS_MODE].y = 77;
- d[SI_AFS_MODE].len = 100;
-
- d[SI_ATTRIBUTES_TXT].prefix = "";
- d[SI_ATTRIBUTES_TXT].postfix = "";
- d[SI_ATTRIBUTES_TXT].color.fg = COLOR_YELLOW;
- d[SI_ATTRIBUTES_TXT].color.bg = COLOR_BLACK;
- d[SI_ATTRIBUTES_TXT].align = CENTER;
- d[SI_ATTRIBUTES_TXT].x = 0;
- d[SI_ATTRIBUTES_TXT].y = 87;
- d[SI_ATTRIBUTES_TXT].len = 100;
-
- d[SI_DIRECTORY].prefix = "dir: ";
- d[SI_DIRECTORY].postfix = "";
- d[SI_DIRECTORY].color.fg = COLOR_YELLOW;
- d[SI_DIRECTORY].color.bg = COLOR_BLACK;
- d[SI_DIRECTORY].align = CENTER;
- d[SI_DIRECTORY].x = 0;
- d[SI_DIRECTORY].y = 97;
- d[SI_DIRECTORY].len = 100;
+ d[SI_play_time].prefix = "";
+ d[SI_play_time].postfix = "";
+ d[SI_play_time].color.fg = COLOR_CYAN;
+ d[SI_play_time].color.bg = COLOR_BLACK;
+ d[SI_play_time].align = CENTER;
+ d[SI_play_time].x = 0;
+ d[SI_play_time].y = 7;
+ d[SI_play_time].len = 35;
+
+ d[SI_basename].prefix = "";
+ d[SI_basename].postfix = "";
+ d[SI_basename].color.fg = COLOR_CYAN;
+ d[SI_basename].color.bg = COLOR_BLACK;
+ d[SI_basename].align = LEFT;
+ d[SI_basename].x = 35;
+ d[SI_basename].y = 7;
+ d[SI_basename].len = 65;
+
+ d[SI_status].prefix = "";
+ d[SI_status].postfix = " ";
+ d[SI_status].color.fg = COLOR_RED;
+ d[SI_status].color.bg = COLOR_BLACK;
+ d[SI_status].align = RIGHT;
+ d[SI_status].x = 0;
+ d[SI_status].y = 17;
+ d[SI_status].len = 11;
+
+ d[SI_status_flags].prefix = "(";
+ d[SI_status_flags].postfix = ")";
+ d[SI_status_flags].color.fg = COLOR_RED;
+ d[SI_status_flags].color.bg = COLOR_BLACK;
+ d[SI_status_flags].align = LEFT;
+ d[SI_status_flags].x = 11;
+ d[SI_status_flags].y = 17;
+ d[SI_status_flags].len = 10;
+
+ d[SI_image_id].prefix = "img: ";
+ d[SI_image_id].postfix = "";
+ d[SI_image_id].color.fg = COLOR_RED;
+ d[SI_image_id].color.bg = COLOR_BLACK;
+ d[SI_image_id].align = CENTER;
+ d[SI_image_id].x = 21;
+ d[SI_image_id].y = 17;
+ d[SI_image_id].len = 10;
+
+ d[SI_lyrics_id].prefix = "lyr: ";
+ d[SI_lyrics_id].postfix = "";
+ d[SI_lyrics_id].color.fg = COLOR_RED;
+ d[SI_lyrics_id].color.bg = COLOR_BLACK;
+ d[SI_lyrics_id].align = CENTER;
+ d[SI_lyrics_id].x = 31;
+ d[SI_lyrics_id].y = 17;
+ d[SI_lyrics_id].len = 11;
+
+ d[SI_format].prefix = "format: ";
+ d[SI_format].postfix = "";
+ d[SI_format].color.fg = COLOR_RED;
+ d[SI_format].color.bg = COLOR_BLACK;
+ d[SI_format].align = CENTER;
+ d[SI_format].x = 42;
+ d[SI_format].y = 17;
+ d[SI_format].len = 18;
+
+ d[SI_num_played].prefix = "#";
+ d[SI_num_played].postfix = "";
+ d[SI_num_played].color.fg = COLOR_RED;
+ d[SI_num_played].color.bg = COLOR_BLACK;
+ d[SI_num_played].align = LEFT;
+ d[SI_num_played].x = 60;
+ d[SI_num_played].y = 17;
+ d[SI_num_played].len = 5;
+
+ d[SI_bitrate].prefix = "";
+ d[SI_bitrate].postfix = "";
+ d[SI_bitrate].color.fg = COLOR_RED;
+ d[SI_bitrate].color.bg = COLOR_BLACK;
+ d[SI_bitrate].align = CENTER;
+ d[SI_bitrate].x = 65;
+ d[SI_bitrate].y = 17;
+ d[SI_bitrate].len = 13;
+
+ d[SI_frequency].prefix = "";
+ d[SI_frequency].postfix = "";
+ d[SI_frequency].color.fg = COLOR_RED;
+ d[SI_frequency].color.bg = COLOR_BLACK;
+ d[SI_frequency].align = CENTER;
+ d[SI_frequency].x = 78;
+ d[SI_frequency].y = 17;
+ d[SI_frequency].len = 10;
+
+ d[SI_score].prefix = "sc: ";
+ d[SI_score].postfix = "";
+ d[SI_score].color.fg = COLOR_RED;
+ d[SI_score].color.bg = COLOR_BLACK;
+ d[SI_score].align = CENTER;
+ d[SI_score].x = 88;
+ d[SI_score].y = 17;
+ d[SI_score].len = 10;
+
+ d[SI_audiod_status].prefix = "";
+ d[SI_audiod_status].postfix = "";
+ d[SI_audiod_status].color.fg = COLOR_MAGENTA;
+ d[SI_audiod_status].color.bg = COLOR_BLACK;
+ d[SI_audiod_status].align = CENTER;
+ d[SI_audiod_status].x = 0;
+ d[SI_audiod_status].y = 27;
+ d[SI_audiod_status].len = 5;
+
+ d[SI_decoder_flags].prefix = "[";
+ d[SI_decoder_flags].postfix = "]";
+ d[SI_decoder_flags].color.fg = COLOR_MAGENTA;
+ d[SI_decoder_flags].color.bg = COLOR_BLACK;
+ d[SI_decoder_flags].align = CENTER;
+ d[SI_decoder_flags].x = 5;
+ d[SI_decoder_flags].y = 27;
+ d[SI_decoder_flags].len = 10;
+
+ d[SI_mtime].prefix = "mod: ";
+ d[SI_mtime].postfix = "";
+ d[SI_mtime].color.fg = COLOR_MAGENTA;
+ d[SI_mtime].color.bg = COLOR_BLACK;
+ d[SI_mtime].align = CENTER;
+ d[SI_mtime].x = 15;
+ d[SI_mtime].y = 27;
+ d[SI_mtime].len = 22;
+
+ d[SI_file_size].prefix = "";
+ d[SI_file_size].postfix = "kb";
+ d[SI_file_size].color.fg = COLOR_MAGENTA;
+ d[SI_file_size].color.bg = COLOR_BLACK;
+ d[SI_file_size].align = CENTER;
+ d[SI_file_size].x = 37;
+ d[SI_file_size].y = 27;
+ d[SI_file_size].len = 10;
+
+ d[SI_channels].prefix = "";
+ d[SI_channels].postfix = "ch";
+ d[SI_channels].color.fg = COLOR_MAGENTA;
+ d[SI_channels].color.bg = COLOR_BLACK;
+ d[SI_channels].align = CENTER;
+ d[SI_channels].x = 47;
+ d[SI_channels].y = 27;
+ d[SI_channels].len = 5;
+
+ d[SI_last_played].prefix = "lp: ";
+ d[SI_last_played].postfix = "";
+ d[SI_last_played].color.fg = COLOR_MAGENTA;
+ d[SI_last_played].color.bg = COLOR_BLACK;
+ d[SI_last_played].align = CENTER;
+ d[SI_last_played].x = 52;
+ d[SI_last_played].y = 27;
+ d[SI_last_played].len = 21;
+
+ d[SI_num_chunks].prefix = "";
+ d[SI_num_chunks].postfix = "x";
+ d[SI_num_chunks].color.fg = COLOR_MAGENTA;
+ d[SI_num_chunks].color.bg = COLOR_BLACK;
+ d[SI_num_chunks].align = RIGHT;
+ d[SI_num_chunks].x = 73;
+ d[SI_num_chunks].y = 27;
+ d[SI_num_chunks].len = 11;
+
+ d[SI_chunk_time].prefix = "";
+ d[SI_chunk_time].postfix = "ms";
+ d[SI_chunk_time].color.fg = COLOR_MAGENTA;
+ d[SI_chunk_time].color.bg = COLOR_BLACK;
+ d[SI_chunk_time].align = LEFT;
+ d[SI_chunk_time].x = 84;
+ d[SI_chunk_time].y = 27;
+ d[SI_chunk_time].len = 8;
+
+ d[SI_amplification].prefix = "amp:";
+ d[SI_amplification].postfix = "";
+ d[SI_amplification].color.fg = COLOR_MAGENTA;
+ d[SI_amplification].color.bg = COLOR_BLACK;
+ d[SI_amplification].align = RIGHT;
+ d[SI_amplification].x = 92;
+ d[SI_amplification].y = 27;
+ d[SI_amplification].len = 8;
+
+ d[SI_techinfo].prefix = "";
+ d[SI_techinfo].postfix = "";
+ d[SI_techinfo].color.fg = COLOR_GREEN;
+ d[SI_techinfo].color.bg = COLOR_BLACK;
+ d[SI_techinfo].align = CENTER;
+ d[SI_techinfo].x = 0;
+ d[SI_techinfo].y = 43;
+ d[SI_techinfo].len = 100;
+
+ d[SI_title].prefix = "";
+ d[SI_title].postfix = ",";
+ d[SI_title].color.fg = COLOR_GREEN;
+ d[SI_title].color.bg = COLOR_BLACK;
+ d[SI_title].align = RIGHT;
+ d[SI_title].x = 0;
+ d[SI_title].y = 53;
+ d[SI_title].len = 45;
+
+ d[SI_artist].prefix = " by ";
+ d[SI_artist].postfix = "";
+ d[SI_artist].color.fg = COLOR_GREEN;
+ d[SI_artist].color.bg = COLOR_BLACK;
+ d[SI_artist].align = LEFT;
+ d[SI_artist].x = 45;
+ d[SI_artist].y = 53;
+ d[SI_artist].len = 45;
+
+ d[SI_year].prefix = "(";
+ d[SI_year].postfix = ")";
+ d[SI_year].color.fg = COLOR_GREEN;
+ d[SI_year].color.bg = COLOR_BLACK;
+ d[SI_year].align = RIGHT;
+ d[SI_year].x = 90;
+ d[SI_year].y = 53;
+ d[SI_year].len = 10;
+
+ d[SI_album].prefix = "A: ";
+ d[SI_album].postfix = ",";
+ d[SI_album].color.fg = COLOR_GREEN;
+ d[SI_album].color.bg = COLOR_BLACK;
+ d[SI_album].align = RIGHT;
+ d[SI_album].x = 0;
+ d[SI_album].y = 63;
+ d[SI_album].len = 50;
+
+ d[SI_comment].prefix = " C: ";
+ d[SI_comment].postfix = "";
+ d[SI_comment].color.fg = COLOR_GREEN;
+ d[SI_comment].color.bg = COLOR_BLACK;
+ d[SI_comment].align = LEFT;
+ d[SI_comment].x = 50;
+ d[SI_comment].y = 63;
+ d[SI_comment].len = 50;
+
+ d[SI_afs_mode].prefix = "";
+ d[SI_afs_mode].postfix = "";
+ d[SI_afs_mode].color.fg = COLOR_YELLOW;
+ d[SI_afs_mode].color.bg = COLOR_BLACK;
+ d[SI_afs_mode].align = CENTER;
+ d[SI_afs_mode].x = 0;
+ d[SI_afs_mode].y = 77;
+ d[SI_afs_mode].len = 100;
+
+ d[SI_attributes_txt].prefix = "";
+ d[SI_attributes_txt].postfix = "";
+ d[SI_attributes_txt].color.fg = COLOR_YELLOW;
+ d[SI_attributes_txt].color.bg = COLOR_BLACK;
+ d[SI_attributes_txt].align = CENTER;
+ d[SI_attributes_txt].x = 0;
+ d[SI_attributes_txt].y = 87;
+ d[SI_attributes_txt].len = 100;
+
+ d[SI_directory].prefix = "dir: ";
+ d[SI_directory].postfix = "";
+ d[SI_directory].color.fg = COLOR_YELLOW;
+ d[SI_directory].color.bg = COLOR_BLACK;
+ d[SI_directory].align = CENTER;
+ d[SI_directory].x = 0;
+ d[SI_directory].y = 97;
+ d[SI_directory].len = 100;
}
struct theme_description {
$(lls_suite_dir)/%.m4d: $(lls_m4_dir)/%.suite.m4 | $(lls_suite_dir)
@[ -z "$(Q)" ] || echo 'M4D $<'
-
$(Q) $(M4) -Pg -I $(lls_m4_include_dir) -s $< \
| awk '{if ($$1 ~ /#line/) {gsub(/"/, "", $$3); if ($$3 != "$<") \
print "$(lls_suite_dir)/$(*F).suite: " $$3}}' | sort | uniq > $@
$(lls_suite_dir)/%.suite: $(lls_m4_dir)/%.suite.m4 | $(lls_suite_dir)
+ @[ -z "$(Q)" ] || echo 'M4 $<'
$(Q) $(M4) -Pg -I $(lls_m4_include_dir) -D GIT_VERSION=$(GIT_VERSION) \
-D COPYRIGHT_YEAR=$(COPYRIGHT_YEAR) -D LOGLEVELS=$(LOGLEVELS) \
$< > $@
$(lls_suite_dir)/%.lsg.c: $(lls_suite_dir)/%.suite
@[ -z "$(Q)" ] || echo 'LSGC $<'
- $(Q) lopsubgen --gen-c --output-dir $(lls_suite_dir) < $<
+ $(Q) $(LOPSUBGEN) --gen-c --output-dir $(lls_suite_dir) < $<
$(lls_suite_dir)/%.lsg.h: $(lls_suite_dir)/%.suite
@[ -z "$(Q)" ] || echo 'LSGH $<'
- $(Q) lopsubgen --gen-header --output-dir $(lls_suite_dir) < $<
+ $(Q) $(LOPSUBGEN) --gen-header --output-dir $(lls_suite_dir) < $<
$(lls_suite_dir)/%.lsg.man: $(lls_suite_dir)/%.suite
@[ -z "$(Q)" ] || echo 'LSGM $<'
- $(Q) lopsubgen --gen-man --output-dir $(lls_suite_dir) < $<
+ $(Q) $(LOPSUBGEN) --gen-man --output-dir $(lls_suite_dir) < $<
$(object_dir)/%.o: $(lls_suite_dir)/%.c | $(object_dir)
@[ -z "$(Q)" ] || echo 'CC $<'
also given), chunk time and chunk offsets.
[/help]
- [option full-path]
- short_opt = F
- summary = list full paths, match full paths against patterns
- [help]
- This option is the default, so it does nothing. Deprecated as of
- v0.6.0, scheduled for removal in v0.6.1.
- [/help]
[option basename]
short_opt = b
summary = list and match basenames only
#include "afh.h"
#include "afs.h"
#include "list.h"
-#include "ipc.h"
#include "mm.h"
-#include "sideband.h"
#include "mood.h"
-#include "sched.h"
/**
* Contains statistical data of the currently admissible audio files.
ret = 1;
out:
free_argv(argv);
- if (ret >= 0)
- return ret;
- if (mi) {
+ if (mi && (ret < 0 || !mlpd->m)) { /* mi was not added to any list */
free(mi->parser_data);
free(mi);
}
struct timeval *result);
struct timeval *clock_get_realtime(struct timeval *tv);
-/** The enum of all status items. */
-enum status_items {STATUS_ITEM_ENUM NUM_STAT_ITEMS};
-extern const char *status_item_list[];
-/** Loop over each status item. */
-#define FOR_EACH_STATUS_ITEM(i) for (i = 0; i < NUM_STAT_ITEMS; i++)
-int for_each_stat_item(char *item_buf, size_t num_bytes,
- int (*item_handler)(int, char *));
-
-
/**
* Return a random non-negative integer in an interval.
*
#define PARA_ERROR_LOG(f,...) para_log(LL_ERROR, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
#define PARA_CRIT_LOG(f,...) para_log(LL_CRIT, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
#define PARA_EMERG_LOG(f,...) para_log(LL_EMERG, "%s: " f, __FUNCTION__, ## __VA_ARGS__)
+
+#define STATUS_ITEMS \
+ STATUS_ITEM(basename) \
+ STATUS_ITEM(status) \
+ STATUS_ITEM(num_played) \
+ STATUS_ITEM(mtime) \
+ STATUS_ITEM(bitrate) \
+ STATUS_ITEM(frequency) \
+ STATUS_ITEM(file_size) \
+ STATUS_ITEM(status_flags) \
+ STATUS_ITEM(format) \
+ STATUS_ITEM(score) \
+ STATUS_ITEM(techinfo) \
+ STATUS_ITEM(afs_mode) \
+ STATUS_ITEM(attributes_txt) \
+ STATUS_ITEM(decoder_flags) \
+ STATUS_ITEM(audiod_status) \
+ STATUS_ITEM(play_time) \
+ STATUS_ITEM(attributes_bitmap) \
+ STATUS_ITEM(offset) \
+ STATUS_ITEM(seconds_total) \
+ STATUS_ITEM(stream_start) \
+ STATUS_ITEM(current_time) \
+ STATUS_ITEM(audiod_uptime) \
+ STATUS_ITEM(image_id) \
+ STATUS_ITEM(lyrics_id) \
+ STATUS_ITEM(duration) \
+ STATUS_ITEM(directory) \
+ STATUS_ITEM(lyrics_name) \
+ STATUS_ITEM(image_name) \
+ STATUS_ITEM(path) \
+ STATUS_ITEM(hash) \
+ STATUS_ITEM(channels) \
+ STATUS_ITEM(last_played) \
+ STATUS_ITEM(num_chunks) \
+ STATUS_ITEM(chunk_time) \
+ STATUS_ITEM(amplification) \
+ STATUS_ITEM(artist) \
+ STATUS_ITEM(title) \
+ STATUS_ITEM(year) \
+ STATUS_ITEM(album) \
+ STATUS_ITEM(comment) \
+ STATUS_ITEM(max_chunk_size) \
+
+#define STATUS_ITEM(_name) SI_ ##_name,
+enum status_items {STATUS_ITEMS NUM_STAT_ITEMS};
+#undef STATUS_ITEM
+#define STATUS_ITEM(_name) #_name,
+
+extern const char *status_item_list[];
+/** Loop over each status item. */
+#define FOR_EACH_STATUS_ITEM(i) for (i = 0; i < NUM_STAT_ITEMS; i++)
+int for_each_stat_item(char *item_buf, size_t num_bytes,
+ int (*item_handler)(int, char *));
goto free_cf;
if (ret == -ERRNO_TO_PARA_ERROR(ENOENT) && OPT_GIVEN(CONFIG_FILE))
goto free_cf;
- ret = 0;
server_lpr = cmdline_lpr;
goto success;
}
if (reload) /* config file overrides command line */
ret = lls(lls_merge(cf_lpr, cmdline_lpr, CMD_PTR, &merged_lpr,
&errctx));
- else /* command line options overrride config file options */
+ else /* command line options override config file options */
ret = lls(lls_merge(cmdline_lpr, cf_lpr, CMD_PTR, &merged_lpr,
&errctx));
lls_free_parse_result(cf_lpr, CMD_PTR);
ret = para_accept(sct->listen_fd, &s->rfds, NULL, 0, &new_fd);
if (ret <= 0)
goto out;
- peer_name = remote_name(new_fd);
- PARA_INFO_LOG("got connection from %s, forking\n", peer_name);
mmd->num_connects++;
mmd->active_connections++;
/*
/* parent keeps accepting connections */
return 0;
}
+ peer_name = remote_name(new_fd);
+ PARA_INFO_LOG("accepted connection from %s\n", peer_name);
/* mmd might already have changed at this point */
free(chunk_table);
alarm(ALARM_TIMEOUT);
init_signal_task();
para_unblock_signal(SIGCHLD);
PARA_NOTICE_LOG("initializing virtual streaming system\n");
- init_vss_task(afs_socket, &sched);
+ vss_init(afs_socket, &sched);
init_server_command_task(argc, argv);
if (daemon_pipe >= 0) {
if (write(daemon_pipe, "\0", 1) < 0) {
* This function creates a pipe, the signal pipe, to deliver pending
* signals to the application (Bernstein's trick). It should be called
* during the application's startup part, followed by subsequent calls
- * to para_install_sighandler() for each signal that should be caught.
+ * to \ref para_install_sighandler() for each signal that should be caught.
*
* A generic signal handler is used for all signals simultaneously. When a
* signal arrives, the signal handler writes the number of the signal received
* by checking if the file descriptor of the other end of the signal pipe is
* ready for reading, see select(2).
*
- * \return This function either succeeds or calls exit(2) to terminate the
+ * \return This function either succeeds or calls exit(3) to terminate the
* current process. On success, a signal task structure is returned.
*/
struct signal_task *signal_init_or_die(void)
exit(EXIT_FAILURE);
}
sit->fd_flags = ret;
- sit->must_set_nonblock_flag = (sit->fd_flags & O_NONBLOCK) == 0;
+ sit->must_set_nonblock_flag = (sit->fd_flags & O_NONBLOCK) == 0
+ && !isatty(STDIN_FILENO);
sit->task = task_register(&ti, s);
}
exit(EXIT_FAILURE);
}
sot->fd_flags = ret;
- sot->must_set_nonblock_flag = (sot->fd_flags & O_NONBLOCK) == 0;
+ sot->must_set_nonblock_flag = (sot->fd_flags & O_NONBLOCK) == 0
+ && !isatty(STDOUT_FILENO);
sot->task = task_register(&ti, s);
}
line_handler_t *line_handler, void *private_data);
/**
- * Write the contents of a status item to a para_buffer.
- *
- * \param b The para_buffer.
- * \param n The number of the status item.
- * \param f A format string.
- *
- * \return The return value of the underlying call to para_printf().
- */
+ * Write the contents of a status item to a para_buffer.
+ *
+ * \param b The para_buffer.
+ * \param n The number of the status item.
+ * \param f A format string.
+ *
+ * \return The return value of the underlying call to \ref para_printf().
+ */
#define WRITE_STATUS_ITEM(b, n, f, ...) (\
{ \
if ((b)->flags & PBF_SIZE_PREFIX) { \
let i++
commands[$i]="ls"
required_objects[$i]='ogg_afh'
-cmdline[$i]="ls -l=v -F ${oggs[@]}"
+cmdline[$i]="ls -l=v ${oggs[@]}"
good[$i]='^attributes_txt: 33'
let i++
PARA_NOTICE_LOG("sending FEC EOF\n");
len = vss_get_fec_eof_packet(&buf);
/* Ignore write() errors since we are closing the target anyway. */
- if (write(sc->fd, buf, len) == len)
- ut->sent_fec_eof = true;
+ if (write(sc->fd, buf, len))
+ do_nothing; /* avoid "ignoring return value" warning */
+ ut->sent_fec_eof = true;
}
static void udp_delete_target(struct sender_client *sc, const char *msg)
}
/**
- * Initialize the list of users allowed to connect to to para_server.
+ * Initialize the list of users allowed to connect to para_server.
*
* \param user_list_file The file containing access information.
*
*/
static void vss_send(struct vss_task *vsst)
{
- int i, fec_active = 0;
+ int i;
+ bool fec_active = false;
struct timeval due;
struct fec_client *fc, *tmp_fc;
return;
if (chk_barrier("eof", &vsst->eof_barrier, &due, 1) < 0)
return;
- if (chk_barrier("data send", &vsst->data_send_barrier,
- &due, 1) < 0)
+ if (chk_barrier("data send", &vsst->data_send_barrier, &due, 1) < 0)
return;
list_for_each_entry_safe(fc, tmp_fc, &fec_client_list, node) {
if (fc->state == FEC_STATE_DISABLED)
continue;
if (!next_slice_is_due(fc, NULL)) {
- fec_active = 1;
+ fec_active = true;
continue;
}
if (compute_next_fec_slice(fc, vsst) <= 0)
continue;
PARA_DEBUG_LOG("sending %u:%u (%u bytes)\n", fc->group.num,
fc->current_slice_num, fc->group.slice_bytes);
+ fc->current_slice_num++;
fc->fcp->send_fec(fc->sc, (char *)fc->enc_buf,
fc->group.slice_bytes + FEC_HEADER_SIZE);
- fc->current_slice_num++;
- fec_active = 1;
+ fec_active = true;
}
if (mmd->current_chunk >= mmd->afd.afhi.chunks_total) { /* eof */
if (!fec_active)
mmd->events++;
set_mmd_offset();
}
- /*
- * We call the send function also in case of empty chunks as
- * they might have still some data queued which can be sent in
- * this case.
- */
vss_get_chunk(mmd->current_chunk, vsst, &buf, &len);
for (i = 0; senders[i].name; i++) {
+ /*
+ * We call ->send() even if len is zero because senders
+ * might have data queued which can be sent now.
+ */
if (!senders[i].send)
continue;
senders[i].send(mmd->current_chunk, mmd->chunks_sent,
buf, len, vsst->header_buf, vsst->header_len);
}
- /*
- * Prefault next chunk(s)
- *
- * If the backing device of the memory-mapped audio file is
- * slow and read-ahead is turned off or prevented for some
- * reason, e.g. due to memory pressure, it may take much longer
- * than the chunk interval to get the next chunk on the wire,
- * causing buffer underruns on the client side. Mapping the
- * file with MAP_POPULATE seems to help a bit, but it does not
- * eliminate the delays completely. Moreover, it is supported
- * only on Linux. So we do our own read-ahead here.
- */
- if (mmd->current_chunk > 0) { /* chunk 0 might be on the heap */
- buf += len;
- for (i = 0; i < 5 && buf < vsst->map + vsst->mapsize; i++) {
- __a_unused volatile char x = *buf;
- buf += 4096;
- }
- }
mmd->chunks_sent++;
mmd->current_chunk++;
}
* This also initializes all supported senders and starts streaming
* if the --autoplay command line flag was given.
*/
-void init_vss_task(int afs_socket, struct sched *s)
+void vss_init(int afs_socket, struct sched *s)
{
static struct vss_task vss_task_struct, *vsst = &vss_task_struct;
int i;
- char *hn = para_hostname(), *home = para_homedir();
long unsigned announce_time = OPT_UINT32_VAL(ANNOUNCE_TIME),
autoplay_delay = OPT_UINT32_VAL(AUTOPLAY_DELAY);
vsst->header_interval.tv_sec = 5; /* should this be configurable? */
PARA_NOTICE_LOG("initializing %s sender\n", senders[i].name);
senders[i].init(&senders[i]);
}
- free(hn);
- free(home);
mmd->sender_cmd_data.cmd_num = -1;
if (OPT_GIVEN(AUTOPLAY)) {
struct timeval tmp;
/** \file vss.h Exported functions from vss.c (para_server). */
-void init_vss_task(int afs_socket, struct sched *s);
+void vss_init(int afs_socket, struct sched *s);
unsigned int vss_playing(void);
unsigned int vss_next(void);
unsigned int vss_repos(void);
git clone git://git.tuebingen.mpg.de/osl
-- [openssl](http://www.openssl.org/) or
+- [openssl](https://www.openssl.org/) or
[libgcrypt](ftp://ftp.gnupg.org/gcrypt/libgcrypt/). At least one
of these two libraries is needed as the backend for cryptographic
routines on both the server and the client side. Both openssl and
not necessary on the server side, i.e., for sending MP3 files.
- [libid3tag](http://www.underbit.com/products/mad/). For version-2
-ID3 tag support, you willl need the libid3tag development package
+ID3 tag support, you will need the libid3tag development package
`libid3tag0-dev`. Without libid3tag, only version-1 tags are
recognized. The mp3 tagger also needs this library for modifying
(id3v1 and id3v2) tags.
-- [ogg vorbis](http://www.xiph.org/downloads/). For ogg vorbis streams
+- [ogg vorbis](https://www.xiph.org/downloads/). For ogg vorbis streams
you need libogg, libvorbis, libvorbisfile. The corresponding Debian
packages are called `libogg-dev` and `libvorbis-dev`.
libfaad package. Install the faad library from sources (available
through the above link) to get the mp4ff library and header files.
-- [speex](http://www.speex.org/). In order to stream or decode speex
+- [speex](https://www.speex.org/). In order to stream or decode speex
files, libspeex (`libspeex-dev`) is required.
-- [flac](http://flac.sourceforge.net/). To stream or decode files
+- [flac](https://xiph.org/flac/). To stream or decode files
encoded with the _Free Lossless Audio Codec_, libFLAC (`libFLAC-dev`)
must be installed.
- [alsa-lib](ftp://ftp.alsa-project.org/pub/lib/). On Linux, you will
need to have the ALSA development package `libasound2-dev` installed.
-- [libao](http://downloads.xiph.org/releases/ao/). Needed to build
+- [libao](https://ftp.osuosl.org/pub/xiph/releases/ao/). Needed to build
the ao writer (ESD, PulseAudio,...). Debian package: `libao-dev`.
- [curses](ftp://ftp.gnu.org/pub/gnu/ncurses). Needed for
- UDP. Recommended for multicast LAN streaming.
-See the Appendix on [network protocols](/#Network.protocols)
+See the Appendix on [network protocols](#Network.protocols)
for brief descriptions of the various protocols relevant for network
audio streaming with paraslash.
the configure file which is shipped in the tarballs but has to be
generated when compiling from git.
-- [discount](http://www.pell.portland.or.us/~orc/Code/discount). The
+- [discount](http://www.pell.portland.or.us/~orc/Code/discount/). The
HTML version of this manual and some of the paraslash web pages are
written in the Markdown markup language and are translated into html
with the converter of the *Discount* package.
The preferred coding style for paraslash coincides more or less
with the style of the Linux kernel. So rather than repeating what is
-written [there](http://www.kernel.org/doc/Documentation/process/coding-style.rst),
+written [there](https://www.kernel.org/doc/Documentation/process/coding-style.rst),
here are the most important points.
- Burn the GNU coding standards.
---------------------
- [paraslash](http://people.tuebingen.mpg.de/maan/paraslash/)
-- [xmms](http://xmms2.org/wiki/Main_Page)
+- [xmms](https://xmms2.org/wiki/Main_Page)
- [mpg123](http://www.mpg123.de/)
-- [gstreamer](http://gstreamer.freedesktop.org/)
+- [gstreamer](https://gstreamer.freedesktop.org/)
- [icecast](http://www.icecast.org/)
-- [Audio Compress](http://beesbuzz.biz/code/audiocompress.php)
+- [Audio Compress](https://beesbuzz.biz/code/audiocompress.php)
External documentation
----------------------
- [The mathematics of
-Raid6](http://kernel.org/pub/linux/kernel/people/hpa/raid6.pdf)
+Raid6](https://www.kernel.org/pub/linux/kernel/people/hpa/raid6.pdf)
by H. Peter Anvin
- [Effective Erasure Codes for reliable Computer Communication
ret = convert_utf8_to_utf16(tags->artist, &artist);
if (ret < 0)
return ret;
+ assert(artist);
artist_bytes = ret;
ret = convert_utf8_to_utf16(tags->title, &title);
if (ret < 0)
goto out;
+ assert(title);
title_bytes = ret;
ret = convert_utf8_to_utf16(tags->comment, &comment);
if (ret < 0)
goto out;
+ assert(comment);
comment_bytes = ret;
if (cdo) {
ret = convert_utf8_to_utf16(tags->album, &album);
if (ret < 0)
return ret;
+ assert(album);
album_bytes = ret;
ret = convert_utf8_to_utf16(tags->year, &year);
if (ret < 0)
goto out;
+ assert(year);
year_bytes = ret;
result->size = 16 + 8 + 2; /* GUID, size, count */
/* name_length + name + null + data type + val length + val */
* This decoder handles Microsoft Windows Media Audio data version 2.
*/
-#define _XOPEN_SOURCE 600
-
#include <math.h>
#include <regex.h>
#include <sys/select.h>
struct vlc coef_vlc[2];
uint16_t *run_table[2];
uint16_t *level_table[2];
- const struct coef_vlc_table *coef_vlcs[2];
/** Frame length in samples. */
int frame_len;
/** log2 of frame_len. */
int block_len;
/** Current position in frame. */
int block_pos;
- /** True if mid/side stereo mode. */
- uint8_t ms_stereo;
/** True if channel is coded. */
uint8_t channel_coded[MAX_CHANNELS];
/** log2 ratio frame/exp. length. */
window[i] = sinf((i + 0.5) * (M_PI / (2.0 * n)));
}
-static void wmadec_cleanup(struct private_wmadec_data *pwd)
-{
- int i;
-
- for (i = 0; i < pwd->nb_block_sizes; i++)
- imdct_end(pwd->mdct_ctx[i]);
- if (pwd->ahi.use_exp_vlc)
- free_vlc(&pwd->exp_vlc);
- if (pwd->use_noise_coding)
- free_vlc(&pwd->hgain_vlc);
- for (i = 0; i < 2; i++) {
- free_vlc(&pwd->coef_vlc[i]);
- free(pwd->run_table[i]);
- free(pwd->level_table[i]);
- }
-}
-
-static void init_coef_vlc(struct vlc *vlc, uint16_t **prun_table,
- uint16_t **plevel_table, const struct coef_vlc_table *vlc_table)
+static void init_coef_vlc(struct private_wmadec_data *pwd, int sidx, int didx)
{
- int n = vlc_table->n;
- const uint8_t *table_bits = vlc_table->huffbits;
- const uint32_t *table_codes = vlc_table->huffcodes;
- const uint16_t *levels_table = vlc_table->levels;
- uint16_t *run_table, *level_table;
- int i, l, j, k, level;
+ const struct coef_vlc_table *src = coef_vlcs + sidx;
+ struct vlc *dst = pwd->coef_vlc + didx;
+ int i, l, j, k, level, n = src->n;
- init_vlc(vlc, VLCBITS, n, table_bits, table_codes, 4);
-
- run_table = para_malloc(n * sizeof(uint16_t));
- level_table = para_malloc(n * sizeof(uint16_t));
+ init_vlc(dst, VLCBITS, n, src->huffbits, src->huffcodes, 4);
+ pwd->run_table[didx] = para_malloc(n * sizeof(uint16_t));
+ pwd->level_table[didx] = para_malloc(n * sizeof(uint16_t));
i = 2;
level = 1;
k = 0;
while (i < n) {
- l = levels_table[k++];
+ l = src->levels[k++];
for (j = 0; j < l; j++) {
- run_table[i] = j;
- level_table[i] = level;
+ pwd->run_table[didx][i] = j;
+ pwd->level_table[didx][i] = level;
i++;
}
level++;
}
- *prun_table = run_table;
- *plevel_table = level_table;
}
/* compute the scale factor band sizes for each MDCT block size */
}
/* choose the VLC tables for the coefficients */
- coef_vlc_table = 2;
+ coef_vlc_table = 4;
if (ahi->sample_rate >= 32000) {
if (bps1 < 0.72)
coef_vlc_table = 0;
else if (bps1 < 1.16)
- coef_vlc_table = 1;
+ coef_vlc_table = 2;
}
- pwd->coef_vlcs[0] = &coef_vlcs[coef_vlc_table * 2];
- pwd->coef_vlcs[1] = &coef_vlcs[coef_vlc_table * 2 + 1];
- init_coef_vlc(&pwd->coef_vlc[0], &pwd->run_table[0], &pwd->level_table[0],
- pwd->coef_vlcs[0]);
- init_coef_vlc(&pwd->coef_vlc[1], &pwd->run_table[1], &pwd->level_table[1],
- pwd->coef_vlcs[1]);
+ init_coef_vlc(pwd, coef_vlc_table, 0);
+ init_coef_vlc(pwd, coef_vlc_table + 1, 1);
return 0;
}
last_exp = 36;
while (q < q_end) {
- code = get_vlc(&pwd->gb, pwd->exp_vlc.table, EXPVLCBITS);
+ code = get_vlc(&pwd->gb, &pwd->exp_vlc);
if (code < 0)
return code;
/* NOTE: this offset is the same as MPEG4 AAC ! */
if (val == (int)0x80000000)
val = get_bits(&pwd->gb, 7) - 19;
else {
- int code = get_vlc(&pwd->gb,
- pwd->hgain_vlc.table, HGAINVLCBITS);
+ int code = get_vlc(&pwd->gb, &pwd->hgain_vlc);
if (code < 0)
return code;
val += code - 18;
int ret, n, v, ch, code, bsize;
int coef_nb_bits, total_gain;
int nb_coefs[MAX_CHANNELS];
+ bool ms_stereo = false; /* mid/side stereo mode */
/* compute current block length */
if (pwd->ahi.use_variable_block_len) {
return -E_INCOHERENT_BLOCK_LEN;
if (pwd->ahi.channels == 2)
- pwd->ms_stereo = get_bit(&pwd->gb);
+ ms_stereo = get_bit(&pwd->gb);
v = 0;
for (ch = 0; ch < pwd->ahi.channels; ch++) {
int a = get_bit(&pwd->gb);
* special VLC tables are used for ms stereo because there is
* potentially less energy there
*/
- tindex = (ch == 1 && pwd->ms_stereo);
+ tindex = ch == 1 && ms_stereo;
coef_vlc = &pwd->coef_vlc[tindex];
run_table = pwd->run_table[tindex];
level_table = pwd->level_table[tindex];
eptr = ptr + nb_coefs[ch];
memset(ptr, 0, pwd->block_len * sizeof(int16_t));
for (;;) {
- code = get_vlc(&pwd->gb, coef_vlc->table, VLCBITS);
+ code = get_vlc(&pwd->gb, coef_vlc);
if (code < 0)
return code;
if (code == 1) /* EOB */
}
}
compute_mdct_coefficients(pwd, bsize, total_gain, nb_coefs);
- if (pwd->ms_stereo && pwd->channel_coded[1]) {
+ if (ms_stereo && pwd->channel_coded[1]) {
float a, b;
int i;
/*
n4 = pwd->block_len / 2;
if (pwd->channel_coded[ch])
imdct(pwd->mdct_ctx[bsize], pwd->output, pwd->coefs[ch]);
- else if (!(pwd->ms_stereo && ch == 1))
+ else if (!(ms_stereo && ch == 1))
memset(pwd->output, 0, sizeof(pwd->output));
/* multiply by the window and add in the frame */
return 0;
}
-static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data,
- int *data_size, const uint8_t *buf, int buf_size)
+static int wma_decode_superframe(struct private_wmadec_data *pwd, void *out,
+ int *out_size, const uint8_t *in)
{
- int ret;
- int16_t *samples;
+ int ret, in_size = pwd->ahi.packet_size - WMA_FRAME_SKIP;
+ int16_t *samples = out;
- if (buf_size == 0) {
- pwd->last_superframe_len = 0;
- *data_size = 0;
- return 0;
- }
- if (buf_size < pwd->ahi.block_align) {
- *data_size = 0;
- return 0;
- }
- buf_size = pwd->ahi.block_align;
- samples = data;
- init_get_bits(&pwd->gb, buf, buf_size);
+ init_get_bits(&pwd->gb, in, in_size);
if (pwd->ahi.use_bit_reservoir) {
int i, nb_frames, bit_offset, pos, len;
uint8_t *q;
// PARA_DEBUG_LOG("have %d frames\n", nb_frames);
ret = -E_WMA_OUTPUT_SPACE;
if ((nb_frames + 1) * pwd->ahi.channels * pwd->frame_len
- * sizeof(int16_t) > *data_size)
+ * sizeof(int16_t) > *out_size)
goto fail;
bit_offset = get_bits(&pwd->gb, pwd->byte_offset_bits + 3);
/* read each frame starting from bit_offset */
pos = bit_offset + 4 + 4 + pwd->byte_offset_bits + 3;
- init_get_bits(&pwd->gb, buf + (pos >> 3),
+ init_get_bits(&pwd->gb, in + (pos >> 3),
(MAX_CODED_SUPERFRAME_SIZE - (pos >> 3)));
len = pos & 7;
if (len > 0)
((bit_offset + 4 + 4 + pwd->byte_offset_bits + 3) & ~7);
pwd->last_bitoffset = pos & 7;
pos >>= 3;
- len = buf_size - pos;
+ len = in_size - pos;
ret = -E_WMA_BAD_SUPERFRAME;
if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0)
goto fail;
pwd->last_superframe_len = len;
- memcpy(pwd->last_superframe, buf + pos, len);
+ memcpy(pwd->last_superframe, in + pos, len);
} else {
PARA_DEBUG_LOG("not using bit reservoir\n");
ret = -E_WMA_OUTPUT_SPACE;
- if (pwd->ahi.channels * pwd->frame_len * sizeof(int16_t) > *data_size)
+ if (pwd->ahi.channels * pwd->frame_len * sizeof(int16_t) > *out_size)
goto fail;
/* single frame decode */
ret = wma_decode_frame(pwd, samples);
}
PARA_DEBUG_LOG("frame_len: %d, block_len: %d, outbytes: %d, eaten: %d\n",
pwd->frame_len, pwd->block_len,
- (int)((int8_t *)samples - (int8_t *)data), pwd->ahi.block_align);
- *data_size = (int8_t *)samples - (int8_t *)data;
+ (int)((int8_t *)samples - (int8_t *)out), pwd->ahi.block_align);
+ *out_size = (int8_t *)samples - (int8_t *)out;
return pwd->ahi.block_align;
fail:
/* reset the bit reservoir on errors */
static void wmadec_close(struct filter_node *fn)
{
struct private_wmadec_data *pwd = fn->private_data;
+ int i;
if (!pwd)
return;
- wmadec_cleanup(pwd);
+ for (i = 0; i < pwd->nb_block_sizes; i++)
+ imdct_end(pwd->mdct_ctx[i]);
+ if (pwd->ahi.use_exp_vlc)
+ free_vlc(&pwd->exp_vlc);
+ if (pwd->use_noise_coding)
+ free_vlc(&pwd->hgain_vlc);
+ for (i = 0; i < 2; i++) {
+ free_vlc(&pwd->coef_vlc[i]);
+ free(pwd->run_table[i]);
+ free(pwd->level_table[i]);
+ }
free(fn->private_data);
fn->private_data = NULL;
}
out_size = WMA_OUTPUT_BUFFER_SIZE;
out = para_malloc(out_size);
ret = wma_decode_superframe(pwd, out, &out_size,
- (uint8_t *)in + WMA_FRAME_SKIP, len - WMA_FRAME_SKIP);
+ (uint8_t *)in + WMA_FRAME_SKIP);
if (ret < 0) {
free(out);
goto err;