$(audiod_objs) $(audioc_objs) $(fade_objs) $(server_objs) \
$(write_objs) $(afh_objs) $(play_objs))
deps := $(addprefix $(dep_dir)/, $(filter-out %.cmdline.d, $(all_objs:.o=.d)))
-converted_executables := audioc client fade play recv write filter gui
+converted_executables := audioc client fade play recv write filter gui afh
unconverted_executables := $(filter-out $(converted_executables), $(executables))
+afh_objs += afh.lsg.o
audioc_objs += audioc.lsg.o
audiod_objs += $(addsuffix _cmd.lsg.o, recv filter audiod write) client.lsg.o
client_objs += client.lsg.o
$(oss_ldflags) \
$(alsa_ldflags)
+para_afh \
para_audioc \
para_audiod \
para_client \
/** \file afh.c Paraslash's standalone audio format handler tool. */
#include <regex.h>
+#include <lopsub.h>
+#include "afh.lsg.h"
#include "para.h"
#include "string.h"
-#include "afh.cmdline.h"
#include "fd.h"
#include "afh.h"
#include "error.h"
#include "version.h"
-#include "ggo.h"
/** Array of error strings. */
DEFINE_PARA_ERRLIST;
-static struct afh_args_info conf;
+struct lls_parse_result *lpr;
+
+#define CMD_PTR (lls_cmd(0, afh_suite))
+#define OPT_RESULT(_name) (lls_opt_result(LSG_AFH_PARA_AFH_OPT_ ## _name, lpr))
+#define OPT_GIVEN(_name) (lls_opt_given(OPT_RESULT(_name)))
+#define OPT_STRING_VAL(_name) (lls_string_val(0, OPT_RESULT(_name)))
+#define OPT_UINT32_VAL(_name) (lls_uint32_val(0, OPT_RESULT(_name)))
static int loglevel;
INIT_STDERR_LOGGING(loglevel)
struct taginfo *tags = &afhi->tags;
bool modified = false;
char *tmp_name;
+ const char *arg;
int output_fd = -1, ret;
struct stat sb;
- if (tag_needs_update(conf.year_given, tags->year, conf.year_arg)) {
+ arg = OPT_STRING_VAL(YEAR);
+ if (tag_needs_update(OPT_GIVEN(YEAR), tags->year, arg)) {
free(tags->year);
- tags->year = para_strdup(conf.year_arg);
+ tags->year = para_strdup(arg);
modified = true;
}
- if (tag_needs_update(conf.title_given, tags->title, conf.title_arg)) {
+ arg = OPT_STRING_VAL(TITLE);
+ if (tag_needs_update(OPT_GIVEN(TITLE), tags->title, arg)) {
free(tags->title);
- tags->title = para_strdup(conf.title_arg);
+ tags->title = para_strdup(arg);
modified = true;
}
- if (tag_needs_update(conf.artist_given, tags->artist,
- conf.artist_arg)) {
+ arg = OPT_STRING_VAL(ARTIST);
+ if (tag_needs_update(OPT_GIVEN(ARTIST), tags->artist, arg)) {
free(tags->artist);
- tags->artist = para_strdup(conf.artist_arg);
+ tags->artist = para_strdup(arg);
modified = true;
}
- if (tag_needs_update(conf.album_given, tags->album, conf.album_arg)) {
+ arg = OPT_STRING_VAL(ALBUM);
+ if (tag_needs_update(OPT_GIVEN(ALBUM), tags->album, arg)) {
free(tags->album);
- tags->album = para_strdup(conf.album_arg);
+ tags->album = para_strdup(arg);
modified = true;
}
- if (tag_needs_update(conf.comment_given, tags->comment,
- conf.comment_arg)) {
+ arg = OPT_STRING_VAL(COMMENT);
+ if (tag_needs_update(OPT_GIVEN(COMMENT), tags->comment, arg)) {
free(tags->comment);
- tags->comment = para_strdup(conf.comment_arg);
+ tags->comment = para_strdup(arg);
modified = true;
}
if (!modified) {
tmp_name);
if (ret < 0)
goto out;
- if (conf.backup_given) {
+ if (OPT_GIVEN(BACKUP)) {
char *backup_name = make_message("%s~", name);
ret = xrename(name, backup_name);
free(backup_name);
{
int i;
- if (conf.parser_friendly_given) {
+ if (OPT_GIVEN(PARSER_FRIENDLY)) {
printf("chunk_table: ");
for (i = 0; i <= afhi->chunks_total; i++)
printf("%u ", afhi->chunk_table[i]);
}
}
-__noreturn static void print_help_and_die(void)
+static void handle_help_flags(void)
{
- struct ggo_help h = DEFINE_GGO_HELP(afh);
- int d = conf.detailed_help_given;
- unsigned flags = d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS;
+ char *help;
- ggo_print_help(&h, flags);
- printf("supported audio formats: %s\n", AUDIO_FORMAT_HANDLERS);
+ if (OPT_GIVEN(DETAILED_HELP))
+ help = lls_long_help(CMD_PTR);
+ else if (OPT_GIVEN(HELP) || lls_num_inputs(lpr) == 0)
+ help = lls_short_help(CMD_PTR);
+ else
+ return;
+ printf("%s", help);
+ free(help);
+ printf("Supported audio formats\n %s\n", AUDIO_FORMAT_HANDLERS);
exit(EXIT_SUCCESS);
}
void *audio_file_data;
size_t audio_file_size;
struct afh_info afhi;
+ char *errctx;
- afh_cmdline_parser(argc, argv, &conf);
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
- version_handle_flag("afh", conf.version_given);
- if (conf.help_given || conf.detailed_help_given || conf.inputs_num == 0)
- print_help_and_die();
+ ret = lls(lls_parse(argc, argv, CMD_PTR, &lpr, &errctx));
+ if (ret < 0)
+ goto out;
+ loglevel = OPT_UINT32_VAL(LOGLEVEL);
+ version_handle_flag("afh", OPT_GIVEN(VERSION));
+ handle_help_flags();
afh_init();
- for (i = 0; i < conf.inputs_num; i++) {
+ for (i = 0; i < lls_num_inputs(lpr); i++) {
int ret2;
- ret = mmap_full_file(conf.inputs[i], O_RDONLY, &audio_file_data,
+ const char *path = lls_input(i, lpr);
+ ret = mmap_full_file(path, O_RDONLY, &audio_file_data,
&audio_file_size, &fd);
if (ret < 0) {
- PARA_ERROR_LOG("failed to mmap \"%s\"\n", conf.inputs[i]);
+ PARA_ERROR_LOG("failed to mmap \"%s\"\n", path);
goto out;
}
- ret = compute_afhi(conf.inputs[i], audio_file_data, audio_file_size,
+ ret = compute_afhi(path, audio_file_data, audio_file_size,
fd, &afhi);
if (ret >= 0) {
audio_format_num = ret;
- if (conf.modify_given) {
- ret = rewrite_tags(conf.inputs[i], fd, audio_file_data,
+ if (OPT_GIVEN(MODIFY)) {
+ ret = rewrite_tags(path, fd, audio_file_data,
audio_file_size, audio_format_num, &afhi);
} else {
- printf("File %d: %s\n", i + 1, conf.inputs[i]);
+ printf("File %d: %s\n", i + 1, path);
print_info(audio_format_num, &afhi);
- if (conf.chunk_table_given)
+ if (OPT_GIVEN(CHUNK_TABLE))
print_chunk_table(&afhi);
printf("\n");
}
break;
}
out:
+ if (errctx)
+ PARA_ERROR_LOG("%s\n", errctx);
if (ret < 0)
- PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+ PARA_EMERG_LOG("%s\n", para_strerror(-ret));
return ret < 0? EXIT_FAILURE : EXIT_SUCCESS;
}
AC_SUBST(recv_objs, add_dot_o($recv_objs))
########################################################################### afh
audio_format_handlers="mp3 wma"
-afh_cmdline_objs="afh"
afh_errlist_objs="
afh
string
wma_afh
wma_common
version
- ggo
"
NEED_OGG_OBJECTS && afh_errlist_objs="$afh_errlist_objs ogg_afh_common"
NEED_VORBIS_OBJECTS && {
audio_format_handlers="$audio_format_handlers aac"
fi
-afh_objs="add_cmdline($afh_cmdline_objs) $afh_errlist_objs"
+afh_objs="$afh_errlist_objs"
AC_SUBST(afh_objs, add_dot_o($afh_objs))
########################################################################## play
+++ /dev/null
-args "--unamed-opts=audio_file --no-handle-version --no-handle-help"
-
-purpose "Print information about audio file(s)"
-
-include(header.m4)
-include(loglevel.m4)
-
-<qu>
-
-###################################
-section "printing meta information"
-###################################
-
-option "chunk-table" c
-#~~~~~~~~~~~~~~~~~~~~~
-"print also the chunk table"
-flag off
-details = "
- The 'chunk table' of an audio file is an array of offsets
- within the audio file. Each offset corresponds to chunk
- of encoded data. The exact meaning of 'chunk' depends on
- the audio format.
-
- Programs which are unaware of the particular audio format can
- read the chunk table to obtain the timing information needed
- to stream the file.
-"
-
-option "parser-friendly" p
-#~~~~~~~~~~~~~~~~~~~~~~~~~
-"do not use human-readable output format"
-flag off
-details = "
- Currently this option only affects the format of the chunk table,
- so it has no effect if --chunk-table is not given.
-
- The human-readable output (the default) consists of one output
- line per chunk and the output contains also the chunk number,
- the duration and the size of each chunk. The parser-friendly
- output prints only the offsets, in one line.
-"
-
-#############################
-section "modifying meta tags"
-#############################
-
-option "modify" m
-#~~~~~~~~~~~~~~~~
-"modify (rather than print) tags"
-flag off
-details = "
- When this option is given, para_afh creates the result file
- as a temporary copy of the given file(s), but with meta
- tags changed according to the options below. On errors,
- the temporary file is removed, leaving the original file
- unchanged. On success, if --backup is given, the original
- file is moved away. Finally the temporary file is renamed to
- the name of the original file.
-"
-
-option "backup" b
-"create backup of the original file"
-flag off
-details = "
- The backup suffix is '~', i.e. a single tilde character is appended
- to the given file name.
-"
-
-option "year" y
-#~~~~~~~~~~~~~~
-"set the year tag"
-string typestr="year"
-optional
-
-option "title" t
-#~~~~~~~~~~~~~~~
-"set the title tag"
-string typestr="title"
-optional
-
-option "artist" a
-#~~~~~~~~~~~~~~~~
-"set the artist/author tag"
-string typestr="artist"
-optional
-
-option "album" A
-#~~~~~~~~~~~~~~~
-"set the album tag"
-string typestr="album"
-optional
-
-option "comment" C
-#~~~~~~~~~~~~~~~~~
-"set the comment tag"
-string typestr="comment"
-optional
-
-</qu>
--- /dev/null
+m4_define(PROGRAM, para_afh)
+[suite afh]
+version-string = GIT_VERSION()
+[supercommand para_afh]
+ purpose = print or modify meta information about audio file(s)
+ [description]
+ By default para_afh prints information about the given audio files,
+ such as format, duration, bitrate, etc., and the content of the most
+ common meta tags (artist, title, album, year, comment). In modify
+ mode it changes the meta tags to the values given at the command line.
+ [/description]
+ non-opts-name = file...
+ m4_include(common-option-section.m4)
+ m4_include(help.m4)
+ m4_include(detailed-help.m4)
+ m4_include(version.m4)
+ m4_include(loglevel.m4)
+ [option modify-section]
+ summary = Printing meta information
+ flag ignored
+ [option chunk-table]
+ short_opt = c
+ summary = print also the chunk table
+ [help]
+ The chunk table of an audio file is an array of offsets where each
+ offset corresponds to chunk of encoded data. The exact meaning of
+ chunk depends on the audio format.
+
+ Programs which are unaware of the particular audio format can read the
+ chunk table to obtain the timing information needed to stream the file.
+ [/help]
+ [option parser-friendly]
+ short_opt = p
+ summary = do not use human-readable output format
+ [help]
+ This option only affects the format of the chunk table, so it has no
+ effect if --chunk-table is not given.
+
+ The human-readable output (the default) consists of one output line
+ per chunk and the output contains also the chunk number, the duration
+ and the size of each chunk. The parser-friendly output prints only
+ the offsets, in one line.
+ [/help]
+ [option modify-section]
+ summary = Modifying meta tags
+ flag ignored
+ [option modify]
+ short_opt = m
+ summary = modify (rather than print) tags
+ [help]
+ If this option is given, para_afh creates a temporary copy of the given
+ file(s), with meta tags changed according to the options below. On
+ errors, the temporary file is removed, leaving the original file
+ unchanged. On success, if --backup is given, the original file is
+ moved away. Finally the temporary file is renamed to the name of the
+ original file.
+ [/help]
+ [option backup]
+ short_opt = b
+ summary = create backup of the original file
+ [help]
+ The backup suffix is '~'. That is, a single tilde character is appended
+ to the given file name.
+ [/help]
+ [option year]
+ short_opt = y
+ summary = set the year tag
+ arg_info = required_arg
+ arg_type = string
+ typestr = string
+ [option title]
+ short_opt = t
+ summary = set the title tag
+ arg_info = required_arg
+ arg_type = string
+ typestr = string
+ [option artist]
+ short_opt = a
+ summary = set the artist tag
+ arg_info = required_arg
+ arg_type = string
+ typestr = string
+ [option album]
+ short_opt = A
+ summary = set the album tag
+ arg_info = required_arg
+ arg_type = string
+ typestr = string
+ [option comment]
+ short_opt = C
+ summary = set the comment tag
+ arg_info = required_arg
+ arg_type = string
+ typestr = string