{
int i;
- if (!conf.human_given) {
+ if (conf.parser_friendly_given) {
printf("chunk_table: ");
for (i = 0; i <= afhi->chunks_total; i++)
printf("%u ", afhi->chunk_table[i]);
}
}
-static int cat_file(struct afh_info *afhi, int audio_format_id,
- void *audio_file_data, size_t audio_file_size)
-{
- int ret;
- struct timeval stream_start;
- long unsigned i, first_chunk, last_chunk;
- const char *buf;
- char *header;
- size_t size;
-
- if (conf.begin_chunk_arg < 0) {
- if (-conf.begin_chunk_arg > afhi->chunks_total)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- first_chunk = afhi->chunks_total + conf.begin_chunk_arg;
- } else
- first_chunk = conf.begin_chunk_arg;
- if (conf.end_chunk_given) {
- if (conf.end_chunk_arg < 0) {
- if (-conf.end_chunk_arg > afhi->chunks_total)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- last_chunk = afhi->chunks_total + conf.end_chunk_arg;
- } else {
- if (conf.end_chunk_arg >= afhi->chunks_total)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- last_chunk = conf.end_chunk_arg;
- }
- } else
- last_chunk = afhi->chunks_total - 1;
- if (first_chunk >= last_chunk)
- return -ERRNO_TO_PARA_ERROR(EINVAL);
- if (!afhi->chunks_total)
- return 1;
- /* eliminate the possibility of short writes */
- ret = mark_fd_blocking(STDOUT_FILENO);
- if (ret < 0)
- return ret;
- if (first_chunk > 0 && !conf.no_header_given) {
- afh_get_header(afhi, audio_format_id, audio_file_data, audio_file_size,
- &header, &size);
- if (size > 0) {
- PARA_INFO_LOG("writing header (%zu bytes)\n", size);
- ret = write_all(STDOUT_FILENO, header, size);
- afh_free_header(header, audio_format_id);
- if (ret < 0)
- return ret;
- if (ret != size)
- return -E_AFH_SHORT_WRITE;
- }
- }
- PARA_NOTICE_LOG("writing chunks %lu - %lu\n", first_chunk, last_chunk);
- gettimeofday(&stream_start, NULL);
- for (i = first_chunk; i <= last_chunk; i++) {
- struct timeval now, diff, next_chunk;
- afh_get_chunk(i, afhi, audio_file_data, &buf, &size);
- PARA_DEBUG_LOG("chunk %lu: size %zu\n", i, size);
- if (conf.just_in_time_given) {
- compute_chunk_time(i - first_chunk, &afhi->chunk_tv,
- &stream_start, &next_chunk);
- gettimeofday(&now, NULL);
- ret = tv_diff(&next_chunk, &now, &diff);
- if (ret > 0) {
- ret = para_select(1, NULL, NULL, &diff);
- if (ret < 0)
- return ret;
- }
- }
- if (!size)
- continue;
- PARA_INFO_LOG("writing chunk %lu\n", i);
- ret = write_all(STDOUT_FILENO, buf, size);
- if (ret < 0)
- return ret;
- }
- return 1;
-}
-
/**
* The main function of para_afh.
*
ret = -E_AFH_SYNTAX;
if (conf.inputs_num == 0)
goto out;
- if (conf.stream_given && conf.inputs_num != 1)
- goto out;
afh_init();
for (i = 0; i < conf.inputs_num; i++) {
int ret2;
goto out;
audio_format_num = ret;
- if (conf.stream_given)
- ret = cat_file(&afhi, audio_format_num,
- audio_file_data, audio_file_size);
- else {
- printf("File %d: %s\n", i + 1, conf.inputs[i]);
- print_info(audio_format_num, &afhi);
- if (conf.chunk_table_given)
- print_chunk_table(&afhi);
- printf("\n");
- }
+ printf("File %d: %s\n", i + 1, conf.inputs[i]);
+ print_info(audio_format_num, &afhi);
+ if (conf.chunk_table_given)
+ print_chunk_table(&afhi);
+ printf("\n");
clear_afhi(&afhi);
ret2 = para_munmap(audio_file_data, audio_file_size);
if (ret2 < 0 && ret >= 0)
include(header.m4)
<qu>
text "
-para_afh, the audio format handler tool, is a stand-alone program
-contained in the paraslash package for analyzing and streaming audio
-files. It can be used to
-
- - print tech info about the given audio file to stdout.
- In particular, the 'chunk table' of the audio file, an array
- of offsets within the audio file, may be printed. This table
- can be used by other programs unaware of the particular audio
- format to stream the audio file.
-
- - write selected parts of the given audio file in complete
- chunks without decoding. Thus para_afh can be used to 'cut'
- an audio file.
-
- - write selected parts of the given audio files 'just in time'
- to stdout. This may be useful for third-party software that
- is capable of reading from stdin.
+para_afh, the audio format handler tool, is a simple program for analyzing
+audio files. It prints technical information about the given audio file to
+stdout.
"
</qu>
include(loglevel.m4)
<qu>
-defgroup "mode"
-#--------------
-groupdesc="
- There are two modes of operation: Info mode and stream mode,
- one of which must be selected by the corresponding option.
- See below.
-"
-required
-
-groupoption "info" i
-#~~~~~~~~~~~~~~~~~~~
-"select info mode"
-group="mode"
-details="
- In this mode, the program prints technical information about
- the given audio file to stdout.
-"
-
-groupoption "stream" s
-#~~~~~~~~~~~~~~~~~~~~~
-"select stream mode"
-group="mode"
-details="
- If this mode is selected, the selected parts of the content
- of the audio file are written to stdout. Only complete chunks
- with respect of the underlying audio format are written.
- For example, only complete frames in case of mp3 files.
-"
-
-section "Options for info mode"
-#==============================
-
option "chunk_table" c
#~~~~~~~~~~~~~~~~~~~~~
"print also the chunk table"
flag off
-dependon="info"
-
-option "human" u
-#~~~~~~~~~~~~~~~
-"use human-readable output format"
-flag off
-dependon = "info"
details = "
- Currently this option only affects the format of the chunk table,
- so it has no effect if --chunk_table is not given.
+ 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.
- The human-readable output consists of one output line per
- chunk and the output contains also the chunk number, the
- duration and the size of each chunk.
+ Programs which are unaware of the particular audio format can
+ read the chunk table to obtain the timing information needed
+ to stream the file.
"
-section "Options for stream mode"
-#================================
-
-
-option "begin_chunk" b
-#~~~~~~~~~~~~~~~~~~~~~
-"skip a number of chunks"
-int typestr="chunk_num"
-default="0"
-dependon="stream"
-optional
-details="
- The chunk_num argument must be between -num_chunks and
- num_chunks - 1 inclusively where num_chunks is the total number
- of chunks which is printed when using the --info option. If
- chunk_num is negative, the given number of chunks are counted
- backwards from the end of the file. For example --begin_chunk
- -100 instructs para_afh to start output at chunk num_chunks
- - 100. This is mainly useful for cutting off the end of an
- audio file.
-"
-
-option "end_chunk" e
-#~~~~~~~~~~~~~~~~~~~
-"only write up to chunk chunk_num"
-int typestr="chunk_num"
-dependon="stream"
-optional
-details="
- For the chunk_num argument the same rules as for --begin_chunk
- apply. The default is to write up to the last chunk.
-"
-
-option "just_in_time" j
-#~~~~~~~~~~~~~~~~~~~~~~
-"use timed writes"
+option "parser-friendly" p
+#~~~~~~~~~~~~~~~~~~~~~~~~~
+"do not use human-readable output format"
flag off
-dependon="stream"
-details="
- Write the specified chunks of data 'just in time', i.e. the
- write of each chunk is delayed until the time it is needed
- by the decoder/player in order to guarantee an uninterrupted
- audio stream.
-"
+details = "
+ Currently this option only affects the format of the chunk table,
+ so it has no effect if --chunk_table is not given.
-option "no_header" H
-#~~~~~~~~~~~~~~~~~~~
-"do not write an audio file header"
-flag off
-dependon="stream"
-details="
- If an audio format needs information about the audio file
- in a format-specific header in order to be understood by
- the decoding software, a suitable header is automatically
- send. This option changes the default behaviour, i.e. no
- header is written.
+ 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.
"
</qu>