]> git.tuebingen.mpg.de Git - paraslash.git/blob - afh_common.c
afh: Expand documentation of init function declarations.
[paraslash.git] / afh_common.c
1 /*
2  * Copyright (C) 1997 Andre Noll <maan@tuebingen.mpg.de>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file afh_common.c Common audio format handler functions. */
8
9 #include <sys/mman.h> /* mmap */
10 #include <sys/types.h>
11 #include <regex.h>
12
13 #include "para.h"
14 #include "error.h"
15 #include "string.h"
16 #include "afh.h"
17
18 typedef void afh_init_func(struct audio_format_handler *);
19 /*
20  * Declaration of the audio format handler init functions.
21  *
22  * These symbols are referenced in the afl array below.
23  *
24  * Most audio format handlers depend on an external library and are not
25  * compiled in if the library is not installed. Hence it is well possible that
26  * not all of these functions are defined. It does not hurt to declare them
27  * anyway, and this avoids another set of ifdefs.
28  */
29 extern afh_init_func mp3_init, ogg_init, aac_afh_init, wma_afh_init,
30         spx_afh_init, flac_afh_init, opus_afh_init;
31
32 /** The list of all status items */
33 const char *status_item_list[] = {STATUS_ITEM_ARRAY};
34
35 /**
36  * The list of supported audio formats.
37  *
38  * We always define the full array of audio formats even if some audio formats
39  * were not compiled in. This is because for each audio file the number of its
40  * audio format is stored in the database. We don't want that numbers to become
41  * stale just because the user installed a new version of paraslash that
42  * supports a different set of audio formats.
43  *
44  * It can still be easily detected whether an audio format is compiled in by
45  * checking if the init function pointer is not \p NULL.
46  */
47 static struct audio_format_handler afl[] = {
48         {
49                 .name = "mp3",
50                 .init = mp3_init,
51         },
52         {
53                 .name = "ogg",
54 #if defined(HAVE_OGG) && defined(HAVE_VORBIS)
55                 .init = ogg_init,
56 #endif
57         },
58         {
59                 .name = "aac",
60 #if defined(HAVE_FAAD)
61                 .init = aac_afh_init,
62 #endif
63         },
64         {
65                 .name = "wma",
66                 .init = wma_afh_init,
67         },
68         {
69                 .name = "spx",
70 #if defined(HAVE_OGG) && defined(HAVE_SPEEX)
71                 .init = spx_afh_init,
72 #endif
73         },
74         {
75                 .name = "flac",
76 #if defined(HAVE_OGG) && defined(HAVE_FLAC)
77                 .init = flac_afh_init,
78 #endif
79         },
80         {
81                 .name = "opus",
82 #if defined(HAVE_OGG) && defined(HAVE_OPUS)
83                 .init = opus_afh_init,
84 #endif
85         },
86         {
87                 .name = NULL,
88         }
89 };
90
91 static inline int next_audio_format(int format)
92 {
93         for (;;) {
94                 if (!afl[format].name)
95                         return format;
96                 format++;
97                 if (afl[format].init)
98                         return format;
99         }
100 }
101
102 /** Iterate over each supported audio format. */
103 #define FOR_EACH_AUDIO_FORMAT(i) for (i = 0; afl[i].name; i = next_audio_format(i))
104
105 /**
106  * Call the init function of each supported audio format handler.
107  */
108 void afh_init(void)
109 {
110         int i;
111
112         PARA_NOTICE_LOG("supported audio formats: %s\n", AUDIO_FORMAT_HANDLERS);
113         FOR_EACH_AUDIO_FORMAT(i) {
114                 PARA_INFO_LOG("initializing %s handler\n",
115                         audio_format_name(i));
116                 afl[i].init(&afl[i]);
117         }
118 }
119
120 /**
121  * Tell whether an audio format handler provides chunk tables.
122  *
123  * Each audio format handler either provides a chunk table or supports dynamic
124  * chunks.
125  *
126  * \param audio_format_id Offset in the afl array.
127  *
128  * \return True if dynamic chunks are supported, false if the audio format
129  * handler provides chunk tables.
130  */
131 bool afh_supports_dynamic_chunks(int audio_format_id)
132 {
133         return afl[audio_format_id].get_chunk;
134 }
135
136 /**
137  * Guess the audio format judging from filename.
138  *
139  * \param name The filename.
140  *
141  * \return This function returns \p -E_AUDIO_FORMAT if it has no idea what kind
142  * of audio file this might be. Otherwise the (non-negative) number of the
143  * audio format is returned.
144  */
145 int guess_audio_format(const char *name)
146 {
147         int i,j, len = strlen(name);
148
149         FOR_EACH_AUDIO_FORMAT(i) {
150                 for (j = 0; afl[i].suffixes[j]; j++) {
151                         const char *p = afl[i].suffixes[j];
152                         int plen = strlen(p);
153                         if (len < plen + 1)
154                                 continue;
155                         if (name[len - plen - 1] != '.')
156                                 continue;
157                         if (strcasecmp(name + len - plen, p))
158                                 continue;
159 //                      PARA_DEBUG_LOG("might be %s\n", audio_format_name(i));
160                         return i;
161                 }
162         }
163         return -E_AUDIO_FORMAT;
164 }
165
166 /**
167  * Get the name of the given audio format.
168  *
169  * \param i The audio format number.
170  *
171  * \return This returns a pointer to statically allocated memory so it
172  * must not be freed by the caller.
173  */
174 const char *audio_format_name(int i)
175 {
176         if (i < 0 || i >= ARRAY_SIZE(afl) - 1)
177                 return "???";
178         return afl[i].name;
179 }
180
181 static int get_file_info(int format, const char *path, char *data,
182                 size_t size, int fd, struct afh_info *afhi)
183 {
184         int ret;
185         const char *fmt = audio_format_name(format);
186
187         memset(afhi, 0, sizeof(*afhi));
188         ret = afl[format].get_file_info(data, size, fd, afhi);
189         if (ret < 0) {
190                 PARA_WARNING_LOG("%s: %s format not detected: %s\n",
191                         path, fmt, para_strerror(-ret));
192                 return ret;
193         }
194         PARA_NOTICE_LOG("%s: detected %s format\n", path, fmt);
195         return format;
196 }
197
198 /**
199  * Call get_file_info() to obtain an afhi structure.
200  *
201  * \param path The full path of the audio file.
202  * \param data Pointer to the contents of the (mapped) file.
203  * \param size The file size in bytes.
204  * \param fd The open file descriptor.
205  * \param afhi Result pointer.
206  *
207  * \return The number of the audio format on success, \p -E_AUDIO_FORMAT if no
208  * compiled in audio format handler is able to handler the file.
209  *
210  * This function tries to find an audio format handler that can interpret the
211  * file given by \a data and \a size.
212  *
213  * It first tries to determine the audio format from the filename given by \a
214  * path. If this doesn't work, all other audio format handlers are tried until
215  * one is found that can handle the file.
216  */
217 int compute_afhi(const char *path, char *data, size_t size, int fd,
218                 struct afh_info *afhi)
219 {
220         int ret, i, format;
221
222         format = guess_audio_format(path);
223         if (format >= 0) {
224                 ret = get_file_info(format, path, data, size, fd, afhi);
225                 if (ret >= 0)
226                         goto success;
227         }
228         FOR_EACH_AUDIO_FORMAT(i) {
229                 if (i == format) /* we already tried this one to no avail */
230                         continue;
231                 ret = get_file_info(i, path, data, size, fd, afhi);
232                 if (ret >= 0)
233                         goto success;
234         }
235         return -E_AUDIO_FORMAT;
236 success:
237         if (!afhi->techinfo)
238                 afhi->techinfo = para_strdup(NULL);
239         if (!afhi->tags.artist)
240                 afhi->tags.artist = para_strdup(NULL);
241         if (!afhi->tags.title)
242                 afhi->tags.title = para_strdup(NULL);
243         if (!afhi->tags.year)
244                 afhi->tags.year = para_strdup(NULL);
245         if (!afhi->tags.album)
246                 afhi->tags.album = para_strdup(NULL);
247         if (!afhi->tags.comment)
248                 afhi->tags.comment = para_strdup(NULL);
249         PARA_DEBUG_LOG("techinfo: %s\n", afhi->techinfo);
250         PARA_DEBUG_LOG("artist: %s\n", afhi->tags.artist);
251         PARA_DEBUG_LOG("title: %s\n", afhi->tags.title);
252         PARA_DEBUG_LOG("year: %s\n", afhi->tags.year);
253         PARA_DEBUG_LOG("album: %s\n", afhi->tags.album);
254         PARA_DEBUG_LOG("comment: %s\n", afhi->tags.comment);
255         return ret;
256 }
257
258 /**
259  * Deallocate the contents of an afh_info structure.
260  *
261  * \param afhi The structure to clear.
262  *
263  * This only frees the memory the various pointer fields of \a afhi point to.
264  * It does *not* free \a afhi itself.
265  */
266 void clear_afhi(struct afh_info *afhi)
267 {
268         if (!afhi)
269                 return;
270         free(afhi->chunk_table);
271         free(afhi->techinfo);
272         free(afhi->tags.artist);
273         free(afhi->tags.title);
274         free(afhi->tags.year);
275         free(afhi->tags.album);
276         free(afhi->tags.comment);
277 }
278
279 static inline size_t get_chunk_len(long unsigned chunk_num,
280                 const struct afh_info *afhi)
281 {
282         return afhi->chunk_table[chunk_num + 1] - afhi->chunk_table[chunk_num];
283 }
284
285 /**
286  * Get one chunk of audio data.
287  *
288  * This implicitly calls the ->open method of the audio format handler at the
289  * first call.
290  *
291  * \param chunk_num The number of the chunk to get.
292  * \param afhi Describes the audio file.
293  * \param audio_format_id Determines the afh.
294  * \param map The memory mapped audio file.
295  * \param mapsize Passed to the afh's ->open() method.
296  * \param buf Result pointer.
297  * \param len The length of the chunk in bytes.
298  * \param afh_context Value/result, determines whether ->open() is called.
299  *
300  * Upon return, \a buf will point so memory inside \a map. The returned buffer
301  * must therefore not be freed by the caller.
302  *
303  * \return Standard.
304  */
305 __must_check int afh_get_chunk(long unsigned chunk_num, struct afh_info *afhi,
306                 uint8_t audio_format_id, const void *map, size_t mapsize,
307                 const char **buf, size_t *len, void **afh_context)
308 {
309         struct audio_format_handler *afh = afl + audio_format_id;
310
311         if (afh_supports_dynamic_chunks(audio_format_id)) {
312                 int ret;
313
314                 if (!*afh_context) {
315                         ret = afh->open(map, mapsize, afh_context);
316                         if (ret < 0)
317                                 return ret;
318                 }
319                 ret = afl[audio_format_id].get_chunk(chunk_num, *afh_context,
320                         buf, len);
321                 if (ret < 0) {
322                         afh->close(*afh_context);
323                         *afh_context = NULL;
324                 }
325                 return ret;
326         } else {
327                 size_t pos = afhi->chunk_table[chunk_num];
328                 *buf = map + pos;
329                 *len = get_chunk_len(chunk_num, afhi);
330                 return 0;
331         }
332 }
333
334 /**
335  * Deallocate resources allocated due to dynamic chunk handling.
336  *
337  * This function should be called if afh_get_chunk() was called at least once.
338  * It is OK to call it even for audio formats which do not support dynamic
339  * chunks, in which case the function does nothing.
340  *
341  * \param afh_context As returned from the ->open method of the afh.
342  * \param audio_format_id Determines the afh.
343  */
344 void afh_close(void *afh_context, uint8_t audio_format_id)
345 {
346         struct audio_format_handler *afh = afl + audio_format_id;
347
348         if (!afh_supports_dynamic_chunks(audio_format_id))
349                 return;
350         if (!afh->close)
351                 return;
352         if (!afh_context)
353                 return;
354         afh->close(afh_context);
355 }
356
357 /**
358  * Find a suitable start chunk.
359  *
360  * \param approx_chunk_num Upper bound for the chunk number to return.
361  * \param afhi Needed for the chunk table.
362  * \param audio_format_id Determines the afh.
363  *
364  * \return For audio format handlers which support dynamic chunks, the function
365  * returns the given chunk number. Otherwise it returns the first non-empty
366  * chunk <= \a approx_chunk_num.
367  *
368  * \sa \ref afh_get_chunk().
369  */
370 int32_t afh_get_start_chunk(int32_t approx_chunk_num,
371                 const struct afh_info *afhi, uint8_t audio_format_id)
372 {
373         int32_t k;
374
375         if (afh_supports_dynamic_chunks(audio_format_id))
376                 return approx_chunk_num;
377
378         for (k = PARA_MAX(0, approx_chunk_num); k >= 0; k--)
379                 if (get_chunk_len(k, afhi) > 0)
380                         return k;
381         return 0;
382 }
383
384 /**
385  * Get the header of an audio file.
386  *
387  * \param afhi The audio file handler data describing the file.
388  * \param audio_format_id Determines the audio format handler.
389  * \param map The data of the audio file.
390  * \param mapsize The amount of bytes of the mmapped audio file.
391  * \param buf The length of the header is stored here.
392  * \param len Points to a buffer containing the header on return.
393  *
394  * This function sets \a buf to \p NULL and \a len to zero if \a map or \a
395  * afhi is \p NULL, or if the current audio format does not need special
396  * header treatment.
397  *
398  * Otherwise, it is checked whether the audio format handler given by
399  * \a audio_format_id defines a ->get_header() method. If it does, this
400  * method is called to obtain the header. If ->get_header() is \p NULL,
401  * a reference to the first chunk of the audio file is returned.
402  *
403  * Once the header is no longer needed, the caller must call \ref
404  * afh_free_header() to free the resources allocated by this function.
405  */
406 void afh_get_header(struct afh_info *afhi, uint8_t audio_format_id,
407                 void *map, size_t mapsize, char **buf, size_t *len)
408 {
409         struct audio_format_handler *afh = afl + audio_format_id;
410
411         if (!map || !afhi || !afhi->header_len) {
412                 *buf = NULL;
413                 *len = 0;
414                 return;
415         }
416         if (!afh->get_header) {
417                 *len = afhi->header_len;
418                 *buf = map;
419                 return;
420         }
421         afh->get_header(map, mapsize, buf, len);
422 }
423
424 /**
425  * Deallocate any resources obtained from afh_get_header().
426  *
427  * \param header_buf Pointer obtained via afh_get_header().
428  * \param audio_format_id Determines the audio format handler.
429  */
430 void afh_free_header(char *header_buf, uint8_t audio_format_id)
431 {
432         struct audio_format_handler *afh = afl + audio_format_id;
433
434         if (afh->get_header)
435                 free(header_buf);
436 }
437
438 /**
439  * Pretty-print the contents of a struct afh_info into a buffer.
440  *
441  * \param audio_format_num The audio format number.
442  * \param afhi Pointer to the structure that contains the information.
443  * \param result Pretty-printed ahfi is here after the call.
444  *
445  * The \a result buffer is dynamically allocated and should be freed by the
446  * caller.
447  *
448  * \return The number of bytes. This function never fails.
449  */
450 unsigned afh_get_afhi_txt(int audio_format_num, struct afh_info *afhi, char **result)
451 {
452         return xasprintf(result, "%s: %dkbit/s\n" /* bitrate */
453                 "%s: %s\n" /* format */
454                 "%s: %dHz\n" /* frequency */
455                 "%s: %d\n" /* channels */
456                 "%s: %" PRIu32 "\n" /* seconds total */
457                 "%s: %lu: %lu\n" /* chunk time */
458                 "%s: %" PRIu32 "\n" /* num chunks */
459                 "%s: %" PRIu32 "\n" /* max chunk size */
460                 "%s: %s\n" /* techinfo */
461                 "%s: %s\n" /* artist */
462                 "%s: %s\n" /* title */
463                 "%s: %s\n" /* year */
464                 "%s: %s\n" /* album */
465                 "%s: %s\n", /* comment */
466                 status_item_list[SI_BITRATE], afhi->bitrate,
467                 status_item_list[SI_FORMAT], audio_format_name(audio_format_num),
468                 status_item_list[SI_FREQUENCY], afhi->frequency,
469                 status_item_list[SI_CHANNELS], afhi->channels,
470                 status_item_list[SI_SECONDS_TOTAL], afhi->seconds_total,
471                 status_item_list[SI_CHUNK_TIME], (long unsigned)afhi->chunk_tv.tv_sec,
472                         (long unsigned)afhi->chunk_tv.tv_usec,
473                 status_item_list[SI_NUM_CHUNKS], afhi->chunks_total,
474                 status_item_list[SI_MAX_CHUNK_SIZE], afhi->max_chunk_size,
475                 status_item_list[SI_TECHINFO], afhi->techinfo? afhi->techinfo : "",
476                 status_item_list[SI_ARTIST], afhi->tags.artist? afhi->tags.artist : "",
477                 status_item_list[SI_TITLE], afhi->tags.title? afhi->tags.title : "",
478                 status_item_list[SI_YEAR], afhi->tags.year? afhi->tags.year : "",
479                 status_item_list[SI_ALBUM], afhi->tags.album? afhi->tags.album : "",
480                 status_item_list[SI_COMMENT], afhi->tags.comment? afhi->tags.comment : ""
481         );
482 }
483
484 /**
485  * Determine the maximal chunk size by investigating the chunk table.
486  *
487  * \param afhi Value/result.
488  *
489  * This function iterates over the chunk table and sets ->max_chunk_size
490  * accordingly. The function exists only for backward compatibility since as of
491  * version 0.6.0, para_server stores the maximal chunk size in its database.
492  * This function is only called if the database value is zero, indicating that
493  * the file was added by an older server version.
494  */
495 void set_max_chunk_size(struct afh_info *afhi)
496 {
497         uint32_t n, max = 0, old = 0;
498
499         for (n = 0; n <= afhi->chunks_total; n++) {
500                 uint32_t val = afhi->chunk_table[n];
501                 /*
502                  * If the first chunk is the header, do not consider it for the
503                  * calculation of the largest chunk size.
504                  */
505                 if (n == 0 || (n == 1 && afhi->header_len > 0)) {
506                         old = val;
507                         continue;
508                 }
509                 max = PARA_MAX(max, val - old);
510                 old = val;
511         }
512         afhi->max_chunk_size = max;
513 }
514
515 /**
516  * Create a copy of the given file with altered meta tags.
517  *
518  * \param audio_format_id Specifies the audio format.
519  * \param map The (read-only) memory map of the input file.
520  * \param mapsize The size of the input file in bytes.
521  * \param tags The new tags.
522  * \param output_fd Altered file is created using this file descriptor.
523  * \param filename The name of the temporary output file.
524  *
525  * This calls the ->rewrite_tags method of the audio format handler associated
526  * with \a audio_format_id to create a copy of the memory-mapped file given
527  * by \a map and \a mapsize, but with altered tags according to \a tags. If
528  * the audio format handler for \a audio_format_id lacks this optional method,
529  * the function returns (the paraslash error code of) \p ENOTSUP.
530  *
531  * \return Standard.
532  */
533 int afh_rewrite_tags(int audio_format_id, void *map, size_t mapsize,
534                 struct taginfo *tags, int output_fd, const char *filename)
535 {
536         struct audio_format_handler *afh = afl + audio_format_id;
537
538         if (!afh->rewrite_tags)
539                 return -ERRNO_TO_PARA_ERROR(ENOTSUP);
540         return afh->rewrite_tags(map, mapsize, tags, output_fd, filename);
541 }