paraslash Paraslash Audio Streaming
About   News   Download   Documentation   Development

Macros | Functions | Variables
afh_common.c File Reference

Common audio format handler functions. More...

#include <sys/mman.h>
#include <sys/types.h>
#include <regex.h>
#include "para.h"
#include "error.h"
#include "string.h"
#include "afh.h"

Macros

#define ALL_AUDIO_FORMATS
 For each audio file the number of its audio format is stored in the database. More...
 
#define FOR_EACH_AUDIO_FORMAT(i)    for (i = 0; i < NUM_AUDIO_FORMATS; i = next_audio_format(i))
 Iterate over each supported audio format. More...
 

Functions

const char * audio_format_name (int i)
 audio_format_handler More...
 
bool afh_supports_dynamic_chunks (int audio_format_id)
 Tell whether an audio format handler provides chunk tables. More...
 
int guess_audio_format (const char *name)
 Guess the audio format judging from filename. More...
 
int compute_afhi (const char *path, char *data, size_t size, int fd, struct afh_info *afhi)
 Call get_file_info() to obtain an afhi structure. More...
 
void clear_afhi (struct afh_info *afhi)
 Deallocate the contents of an afh_info structure. More...
 
__must_check int afh_get_chunk (long unsigned chunk_num, struct afh_info *afhi, uint8_t audio_format_id, const void *map, size_t mapsize, const char **buf, uint32_t *len, void **afh_context)
 Get one chunk of audio data. More...
 
void afh_close (void *afh_context, uint8_t audio_format_id)
 Deallocate resources allocated due to dynamic chunk handling. More...
 
int32_t afh_get_start_chunk (int32_t approx_chunk_num, const struct afh_info *afhi, uint8_t audio_format_id)
 Find a suitable start chunk. More...
 
void afh_get_header (struct afh_info *afhi, uint8_t audio_format_id, void *map, size_t mapsize, char **buf, size_t *len)
 Get the header of an audio file. More...
 
void afh_free_header (char *header_buf, uint8_t audio_format_id)
 Deallocate any resources obtained from afh_get_header(). More...
 
unsigned afh_get_afhi_txt (int audio_format_num, struct afh_info *afhi, char **result)
 Pretty-print the contents of a struct afh_info into a buffer. More...
 
void set_max_chunk_size (struct afh_info *afhi)
 Determine the maximal chunk size by investigating the chunk table. More...
 
int afh_rewrite_tags (int audio_format_id, void *map, size_t mapsize, struct taginfo *tags, int output_fd, const char *filename)
 Create a copy of the given file with altered meta tags. More...
 

Variables

const char * status_item_list [] = {STATUS_ITEMS}
 The list of all status items. More...
 

Detailed Description

Common audio format handler functions.

Macro Definition Documentation

◆ ALL_AUDIO_FORMATS

#define ALL_AUDIO_FORMATS
Value:
AUDIO_FORMAT(mp3) \
AUDIO_FORMAT(ogg) \
AUDIO_FORMAT(aac) \
AUDIO_FORMAT(wma) \
AUDIO_FORMAT(spx) \
AUDIO_FORMAT(flac) \
AUDIO_FORMAT(opus) \

For each audio file the number of its audio format is stored in the database.

Therefore this list, in particular its order, is part of the ABI. So it's only OK to append new audio formats. All audio formats are listed here, regardless of whether the audio format handler is compiled in.

◆ FOR_EACH_AUDIO_FORMAT

#define FOR_EACH_AUDIO_FORMAT (   i)     for (i = 0; i < NUM_AUDIO_FORMATS; i = next_audio_format(i))

Iterate over each supported audio format.

Function Documentation

◆ audio_format_name()

const char* audio_format_name ( int  i)

audio_format_handler

Get the name of the given audio format.

Parameters
iThe audio format number.
Returns
This returns a pointer to statically allocated memory so it must not be freed by the caller.

References NUM_AUDIO_FORMATS.

Referenced by afh_get_afhi_txt().

◆ afh_supports_dynamic_chunks()

bool afh_supports_dynamic_chunks ( int  audio_format_id)

Tell whether an audio format handler provides chunk tables.

Each audio format handler either provides a chunk table or supports dynamic chunks.

Parameters
audio_format_idOffset in the afl array.
Returns
True if dynamic chunks are supported, false if the audio format handler provides chunk tables.

References audio_format_handler::get_chunk.

Referenced by afh_close(), afh_get_chunk(), and afh_get_start_chunk().

◆ guess_audio_format()

int guess_audio_format ( const char *  name)

Guess the audio format judging from filename.

Parameters
nameThe filename.
Returns
This function returns -E_AUDIO_FORMAT if it has no idea what kind of audio file this might be. Otherwise the (non-negative) number of the audio format is returned.

References FOR_EACH_AUDIO_FORMAT, and audio_format_handler::suffixes.

Referenced by compute_afhi().

◆ compute_afhi()

int compute_afhi ( const char *  path,
char *  data,
size_t  size,
int  fd,
struct afh_info afhi 
)

Call get_file_info() to obtain an afhi structure.

Parameters
pathThe full path of the audio file.
dataPointer to the contents of the (mapped) file.
sizeThe file size in bytes.
fdThe open file descriptor.
afhiResult pointer.
Returns
The number of the audio format on success, -E_AUDIO_FORMAT if no compiled in audio format handler is able to handler the file.

This function tries to find an audio format handler that can interpret the file given by data and size.

It first tries to determine the audio format from the filename given by path. If this doesn't work, all other audio format handlers are tried until one is found that can handle the file.

References guess_audio_format().

◆ clear_afhi()

void clear_afhi ( struct afh_info afhi)

Deallocate the contents of an afh_info structure.

Parameters
afhiThe structure to clear.

This only frees the memory the various pointer fields of afhi point to. It does not free afhi itself.

References taginfo::album, taginfo::artist, afh_info::chunk_table, taginfo::comment, afh_info::tags, afh_info::techinfo, taginfo::title, and taginfo::year.

◆ afh_get_chunk()

__must_check int afh_get_chunk ( long unsigned  chunk_num,
struct afh_info afhi,
uint8_t  audio_format_id,
const void *  map,
size_t  mapsize,
const char **  buf,
uint32_t *  len,
void **  afh_context 
)

Get one chunk of audio data.

This implicitly calls the ->open method of the audio format handler at the first call.

Parameters
chunk_numThe number of the chunk to get.
afhiDescribes the audio file.
audio_format_idDetermines the afh.
mapThe memory mapped audio file.
mapsizePassed to the afh's ->open() method.
bufResult pointer.
lenThe length of the chunk in bytes.
afh_contextValue/result, determines whether ->open() is called.

Upon return, buf will point so memory inside map. The returned buffer must therefore not be freed by the caller.

Returns
Standard.

References afh_supports_dynamic_chunks(), afh_info::chunk_table, audio_format_handler::close, audio_format_handler::get_chunk, and audio_format_handler::open.

◆ afh_close()

void afh_close ( void *  afh_context,
uint8_t  audio_format_id 
)

Deallocate resources allocated due to dynamic chunk handling.

This function should be called if afh_get_chunk() was called at least once. It is OK to call it even for audio formats which do not support dynamic chunks, in which case the function does nothing.

Parameters
afh_contextAs returned from the ->open method of the afh.
audio_format_idDetermines the afh.

References afh_supports_dynamic_chunks(), and audio_format_handler::close.

◆ afh_get_start_chunk()

int32_t afh_get_start_chunk ( int32_t  approx_chunk_num,
const struct afh_info afhi,
uint8_t  audio_format_id 
)

Find a suitable start chunk.

Parameters
approx_chunk_numUpper bound for the chunk number to return.
afhiNeeded for the chunk table.
audio_format_idDetermines the afh.
Returns
For audio format handlers which support dynamic chunks, the function returns the given chunk number. Otherwise it returns the first non-empty chunk <= approx_chunk_num.
See also
afh_get_chunk().

References afh_supports_dynamic_chunks(), and PARA_MAX.

◆ afh_get_header()

void afh_get_header ( struct afh_info afhi,
uint8_t  audio_format_id,
void *  map,
size_t  mapsize,
char **  buf,
size_t *  len 
)

Get the header of an audio file.

Parameters
afhiThe audio file handler data describing the file.
audio_format_idDetermines the audio format handler.
mapThe data of the audio file.
mapsizeThe amount of bytes of the mmapped audio file.
bufThe length of the header is stored here.
lenPoints to a buffer containing the header on return.

This function sets buf to NULL and len to zero if map or afhi is NULL, or if the current audio format does not need special header treatment.

Otherwise, it is checked whether the audio format handler given by audio_format_id defines a ->get_header() method. If it does, this method is called to obtain the header. If ->get_header() is NULL, a reference to the first chunk of the audio file is returned.

Once the header is no longer needed, the caller must call afh_free_header() to free the resources allocated by this function.

References audio_format_handler::get_header, and afh_info::header_len.

◆ afh_free_header()

void afh_free_header ( char *  header_buf,
uint8_t  audio_format_id 
)

Deallocate any resources obtained from afh_get_header().

Parameters
header_bufPointer obtained via afh_get_header().
audio_format_idDetermines the audio format handler.

References audio_format_handler::get_header.

◆ afh_get_afhi_txt()

unsigned afh_get_afhi_txt ( int  audio_format_num,
struct afh_info afhi,
char **  result 
)

Pretty-print the contents of a struct afh_info into a buffer.

Parameters
audio_format_numThe audio format number.
afhiPointer to the structure that contains the information.
resultPretty-printed ahfi is here after the call.

The result buffer is dynamically allocated and should be freed by the caller.

Returns
The number of bytes. This function never fails.

References taginfo::album, taginfo::artist, audio_format_name(), afh_info::bitrate, afh_info::channels, afh_info::chunk_tv, afh_info::chunks_total, taginfo::comment, afh_info::frequency, afh_info::max_chunk_size, afh_info::seconds_total, status_item_list, afh_info::tags, afh_info::techinfo, taginfo::title, xasprintf(), and taginfo::year.

◆ set_max_chunk_size()

void set_max_chunk_size ( struct afh_info afhi)

Determine the maximal chunk size by investigating the chunk table.

Parameters
afhiValue/result.

This function iterates over the chunk table and sets ->max_chunk_size accordingly. The function exists only for backward compatibility since as of version 0.6.0, para_server stores the maximal chunk size in its database. This function is only called if the database value is zero, indicating that the file was added by an older server version.

References afh_info::chunk_table, afh_info::chunks_total, afh_info::header_len, afh_info::max_chunk_size, and PARA_MAX.

◆ afh_rewrite_tags()

int afh_rewrite_tags ( int  audio_format_id,
void *  map,
size_t  mapsize,
struct taginfo tags,
int  output_fd,
const char *  filename 
)

Create a copy of the given file with altered meta tags.

Parameters
audio_format_idSpecifies the audio format.
mapThe (read-only) memory map of the input file.
mapsizeThe size of the input file in bytes.
tagsThe new tags.
output_fdAltered file is created using this file descriptor.
filenameThe name of the temporary output file.

This calls the ->rewrite_tags method of the audio format handler associated with audio_format_id to create a copy of the memory-mapped file given by map and mapsize, but with altered tags according to tags. If the audio format handler for audio_format_id lacks this optional method, the function returns (the paraslash error code of) ENOTSUP.

Returns
Standard.

References ERRNO_TO_PARA_ERROR, and audio_format_handler::rewrite_tags.

Variable Documentation

◆ status_item_list

const char* status_item_list[] = {STATUS_ITEMS}

The list of all status items.

status items

Referenced by afh_get_afhi_txt().