X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=afh.h;h=d2ac93aec96f95a0ca0bf706327f831520145ee7;hb=6bded356ec89b1344049ff702e6c6babaeccd439;hp=35b7a70e4dff72220f4550f4fbecc6dffdc48710;hpb=aee7bc654a67f45556ad2c6dc0e98a06bc95c8ff;p=paraslash.git diff --git a/afh.h b/afh.h index 35b7a70e..d2ac93ae 100644 --- a/afh.h +++ b/afh.h @@ -1,118 +1,157 @@ -/* - * Copyright (C) 2005-2006 Andre Noll - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - */ +/* Copyright (C) 2005 Andre Noll , see file COPYING. */ -/** \file afh.h structures for audio format handling (para_server) */ +/** \file afh.h Structures for audio format handling (para_server). */ -/** \cond */ -#ifdef HAVE_OGGVORBIS -#define OV_AUDIO_FORMAT " ogg" -#define OV_AUDIO_FORMAT_ARRAY , "ogg" -#else -#define OV_AUDIO_FORMAT "" -#define OV_AUDIO_FORMAT_ARRAY -#endif - -#ifdef HAVE_FAAD -#define AAC_AUDIO_FORMAT " aac" -#define AAC_AUDIO_FORMAT_ARRAY , "aac" -#else -#define AAC_AUDIO_FORMAT "" -#define AAC_AUDIO_FORMAT_ARRAY -#endif +/** + * The tags used by all audio format handlers. + * + * Paraslash only uses the more common tags. These are recognized + * for all supported audio formats. + */ +struct taginfo { + /** TPE1 (id3v2) / ARTIST (vorbis) / ART (aac)/ author(spx) */ + char *artist; + /** TIT2/TITLE/nam */ + char *title; + /** TDRC/YEAR/day */ + char *year; + /** TALB/ALBUM/alb */ + char *album; + /** COMM/COMMENT/cmt */ + char *comment; +}; -#define SUPPORTED_AUDIO_FORMATS "mp3" OV_AUDIO_FORMAT AAC_AUDIO_FORMAT -#define SUPPORTED_AUDIO_FORMATS_ARRAY "mp3" OV_AUDIO_FORMAT_ARRAY \ - AAC_AUDIO_FORMAT_ARRAY, NULL +/** Audio format dependent information. */ +struct afh_info { + /** The number of chunks this audio file contains. */ + uint32_t chunks_total; + /** The length of the audio file in seconds. */ + uint32_t seconds_total; + /** Audio handler specific info about the file. */ + char *techinfo; + /** Id3 tags, vorbis comments, aac tags. */ + struct taginfo tags; + /** + * The table that specifies the offset of the individual pieces in + * the current audio file. + */ + uint32_t *chunk_table; + /** Size of the largest chunk, introduced in v0.6.0. */ + uint32_t max_chunk_size; + /** Period of time between sending data chunks. */ + struct timeval chunk_tv; + /** + * The header is needed by senders in case a new client connects in the + * middle of the stream. The length of the header defaults to zero + * which means that this audio format does not need any special header + * treatment. The audio format handler does not need to set this to + * zero in this case. + */ + uint32_t header_len; + /** The number of channels. */ + uint8_t channels; + /** Frequency in Hz. */ + uint16_t frequency; + /** Exact meaning depends on audio format. */ + uint16_t bitrate; +}; -/** \endcond */ +/** Data about the current audio file, passed from afs to server. */ +struct audio_file_data { + /** The open file descriptor to the current audio file. */ + int fd; + /** Vss needs this for streaming. */ + struct afh_info afhi; + /** + * Size of the largest chunk. Superseded by afhi->max_chunk_size. May + * be removed after v0.6.1. + */ + uint32_t max_chunk_size; + /** Needed to get the audio file header. */ + uint8_t audio_format_id; +}; /** - * structure for audio format handling + * Structure for audio format handling. * - * There's exactly one such struct for each supported audio format. Initially, - * only \a name and \a init are defined. During the startup process, - * para_server calls the \a init function of each audio format handler which is - * expected to fill in all the other function pointers. + * There's one such struct for each supported audio format. Initially, only \a + * name and \a init are defined. During the startup process, para_server calls + * the \a init function of each audio format handler which is expected to fill + * in the other part of this struct. */ struct audio_format_handler { - /** - * name of the audio format - */ + /** Name of the audio format. */ const char *name; /** - * typical file endings for files that can be handled by this afh. - */ - const char **suffixes; - /** - * pointer to the audio format handler's init function + * Pointer to the audio format handler's init function. * * Must initialize all function pointers and is assumed to succeed. */ void (*init)(struct audio_format_handler*); + /** Typical file endings for files that can be handled by this afh. */ + const char * const *suffixes; /** - * period of time between sending data chunks - */ - struct timeval chunk_tv; /* length of one chunk of data */ - /** - * end of file timeout - do not load new audio file until this time + * Check if this audio format handler can handle the file. * - */ - struct timeval eof_tv; /* timeout on eof */ - /** - * Pointer to the optional get-header function. + * This is a pointer to a function returning whether a given file is + * valid for this audio format. A negative return value indicates that + * this audio format handler is unable to decode the given file. On + * success, the function must return a positive value and fill in the + * given struct afh_info. * - * This is called from a sender in case a new client connects in the middle of - * the stream. The audio format handler may set this to NULL to indicate that - * this audio format does not need any special header treatment. If non-NULL, - * the function it points to must return a pointer to a buffer holding the - * current audio file header, together with the header length. - */ - char *(*get_header_info)(int *header_len); + * \sa struct \ref afh_info. + */ + int (*get_file_info)(char *map, size_t numbytes, int fd, + struct afh_info *afhi); + /** Optional, used for header-rewriting. See \ref afh_get_header(). */ + void (*get_header)(void *map, size_t mapsize, char **buf, size_t *len); /** - * check if this audio format handler can handle the file + * An audio format handler may signify support for dynamic chunks by + * defining ->get_chunk below. In this case the vss calls ->open() at + * BOS, ->get_chunk() for each chunk while streaming, and ->close() at + * EOS. The chunk table is not accessed at all. * - * This is a pointer to a function returning whether a given file is valid for - * this audio format. A negative return value indicates that this audio format - * handler did not recognize the given file. On success, the function is - * expected to return a positive value and to fill in \arg info_str, \arg - * chunks and \arg seconds appropriately and to return the chunk table - * via \a vss_chunk_table. - */ - int (*get_file_info)(FILE *audio_file, char *info_str, - long unsigned *chunks, int *seconds, size_t **vss_chunk_table); + * The function may return its (opaque) context through the last + * argument. The returned pointer is passed to subsequent calls to + * ->get_chunk() and ->close(). + */ + int (*open)(const void *map, size_t mapsize, void **afh_context); /** - * cleanup function of this audio format handler - * - * This close function should deallocate any resources - * associated with the current audio file. In particular, it is responsible - * for closing the file handle. It is assumed to succeed. - */ - void (*close_audio_file)(void); + * Return a reference to one chunk. The returned pointer points to a + * portion of the memory mapped audio file. The caller must not call + * free() on it. + */ + int (*get_chunk)(long unsigned chunk_num, void *afh_context, + const char **buf, size_t *len); + /** Deallocate the resources occupied by ->open(). */ + void (*close)(void *afh_context); /** - * function responsible for reading one data chunk. + * Write audio file with altered tags, optional. * - * \a read_chunk() must return a pointer to the next chunk of data that should - * be sent out, or \p NULL on errors or if the end of the file was encountered. - * - * If it returns non-NULL, \a len must contain the length of the returned - * buffer (which may be zero if nothing has to be sent for some reason). - * Otherwise, \a len is used to distinguish between the eof and the error case: - * It must be zero in the eof case, or negative if an error occcured. - */ - char * (*read_chunk)(long unsigned chunk_num, ssize_t *len); + * The output file descriptor has been opened by the caller and must not + * be closed in this function. + */ + int (*rewrite_tags)(const char *map, size_t mapsize, struct taginfo *tags, + int output_fd, const char *filename); }; + +void afh_init(void); +int guess_audio_format(const char *name); +int compute_afhi(const char *path, char *data, size_t size, + int fd, struct afh_info *afhi); +const char *audio_format_name(int); +__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, size_t *len, void **afh_context); +void afh_close(void *afh_context, uint8_t audio_format_id); +int32_t afh_get_start_chunk(int32_t approx_chunk_num, + const struct afh_info *afhi, uint8_t audio_format_id); +void afh_get_header(struct afh_info *afhi, uint8_t audio_format_id, + void *map, size_t mapsize, char **buf, size_t *len); +void afh_free_header(char *header_buf, uint8_t audio_format_id); +void clear_afhi(struct afh_info *afhi); +unsigned afh_get_afhi_txt(int audio_format_num, struct afh_info *afhi, char **result); +int afh_rewrite_tags(int audio_format_id, void *map, size_t mapsize, + struct taginfo *tags, int output_fd, const char *filename); +void set_max_chunk_size(struct afh_info *afhi); +bool afh_supports_dynamic_chunks(int audio_format_id);