X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=mp3_afh.c;h=ae7f117bfaeac1841c6883388a4b2e16c7a31a97;hp=cf507ec2b371c187e18123b1cdc5e4be07f6547b;hb=ba30bb8d0bb025c0dad80e5ff47352b4bc130423;hpb=a15abef9eee4b8369b3ce8fcaad91a2e0c879df5 diff --git a/mp3_afh.c b/mp3_afh.c index cf507ec2..ae7f117b 100644 --- a/mp3_afh.c +++ b/mp3_afh.c @@ -1,19 +1,7 @@ /* * Copyright (C) 2003-2007 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. + * Licensed under the GPL v2. For licencing details see COPYING. */ /** \file mp3_afh.c para_server's mp3 audio format handler */ @@ -28,11 +16,10 @@ * Johannes Overmann */ -#include "server.cmdline.h" +#include "para.h" +#include "afh.h" #include "server.h" -#include "vss.h" #include "error.h" -#include "fd.h" #include "string.h" /** \cond some defines and structs which are only used in this file */ @@ -72,8 +59,6 @@ struct mp3info { int id3_isvalid; struct id3tag id3; int vbr; - long unsigned br_average; - int freq; }; /** \endcond */ @@ -115,9 +100,19 @@ static const char *header_mode(struct mp3header *h) h->mode = 4; /* invalid */ return mode_text[h->mode]; } + +static int header_channels(struct mp3header *h) +{ + if (h->mode > 3) + return 0; + if (h->mode < 3) + return 2; + return 1; +} + static int header_bitrate(struct mp3header *h) { - if (h->layer > 3 || h->bitrate > 14) + if (!h->layer || h->layer > 3 || h->bitrate > 14 || !h->bitrate) return -E_HEADER_BITRATE; return mp3info_bitrate[h->version & 1][3 - h->layer][h->bitrate - 1]; } @@ -143,14 +138,14 @@ static void write_info_str(struct audio_format_info *afi) int v = mp3.id3_isvalid; snprintf(afi->info_string, MMD_INFO_SIZE, - "audio_file_info1:%lu x %lums, %lu kbit/s (%cbr) %i KHz %s\n" + "audio_file_info1:%lu x %lums, %u kbit/s (%cbr) %i KHz %s\n" "audio_file_info2:%s, by %s\n" "audio_file_info3:A: %s, Y: %s, C: %s\n", afi->chunks_total, tv2ms(&afi->chunk_tv), - mp3.br_average, + afi->bitrate, mp3.vbr? 'v' : 'c', - mp3.freq / 1000, + afi->frequency / 1000, header_mode(&mp3.header), v && *mp3.id3.title? mp3.id3.title : "(title tag not set)", v && *mp3.id3.artist? mp3.id3.artist : "(artist tag not set)", @@ -195,7 +190,7 @@ static int compare_headers(struct mp3header *h1,struct mp3header *h2) * retrieve a valid frame header, and a negative return value indicates an * error. */ -static int get_header(unsigned char *map, off_t numbytes, off_t *fpos, +static int get_header(unsigned char *map, size_t numbytes, off_t *fpos, struct mp3header *header) { int fl, ret; @@ -234,7 +229,7 @@ out: * Return the length of the next frame header or zero if the end of the file is * reached. */ -static int mp3_seek_next_header(unsigned char *map, off_t numbytes, off_t *fpos) +static int mp3_seek_next_header(unsigned char *map, size_t numbytes, off_t *fpos) { int k, l = 0, first_len; struct mp3header h, h2; @@ -264,7 +259,7 @@ static int mp3_seek_next_header(unsigned char *map, off_t numbytes, off_t *fpos) return 0; } -static void mp3_get_id3(unsigned char *map, off_t numbytes, off_t *fpos) +static void mp3_get_id3(unsigned char *map, size_t numbytes, off_t *fpos) { mp3.id3_isvalid = 0; mp3.id3.title[0] = '\0'; @@ -275,8 +270,8 @@ static void mp3_get_id3(unsigned char *map, off_t numbytes, off_t *fpos) if (numbytes < 128) return; *fpos = numbytes - 128; - if (strncmp("TAG", map + *fpos, 3)) { - PARA_INFO_LOG("%s", "no id3 tag\n"); + if (strncmp("TAG", (char *) map + *fpos, 3)) { + PARA_DEBUG_LOG("%s", "no id3 tag\n"); return; } *fpos = numbytes - 125; @@ -302,7 +297,7 @@ static void mp3_get_id3(unsigned char *map, off_t numbytes, off_t *fpos) unpad(mp3.id3.comment); } -static int find_valid_start(unsigned char *map, off_t numbytes, off_t *fpos) +static int find_valid_start(unsigned char *map, size_t numbytes, off_t *fpos) { int frame_len; @@ -320,7 +315,7 @@ static int find_valid_start(unsigned char *map, off_t numbytes, off_t *fpos) return frame_len; } -static int mp3_read_info(unsigned char *map, off_t numbytes, +static int mp3_read_info(unsigned char *map, size_t numbytes, struct audio_format_info *afi) { long fl_avg = 0, freq_avg = 0, br_avg = 0; @@ -334,19 +329,25 @@ static int mp3_read_info(unsigned char *map, off_t numbytes, mp3_get_id3(map, numbytes, &fpos); fpos = 0; mp3.vbr = 0; - mp3.freq = 0; while (1) { - int freq, br, fl; + unsigned long freq, br, fl; struct timeval tmp, cct; /* current chunk time */ fpos += len; len = find_valid_start(map, numbytes, &fpos); if (len <= 0) break; - freq = header_frequency(&mp3.header); - br = header_bitrate(&mp3.header); - fl = frame_length(&mp3.header); - if (freq < 0 || br < 0 || fl < 0) + ret = header_frequency(&mp3.header); + if (ret < 0) + continue; + freq = ret; + ret = header_bitrate(&mp3.header); + if (ret < 0) + continue; + br = ret; + ret = frame_length(&mp3.header); + if (ret < 0) continue; + fl = ret; tmp.tv_sec = fl; tmp.tv_usec = 0; tv_divide(br * 125, &tmp, &cct); @@ -370,9 +371,9 @@ static int mp3_read_info(unsigned char *map, off_t numbytes, fl_avg = fl; continue; } - freq_avg += (freq - freq_avg) / (afi->chunks_total + 1); - fl_avg += (fl - fl_avg) / (afi->chunks_total + 1); - br_avg += (br - br_avg) / ((long)afi->chunks_total + 1); + freq_avg += ((long)freq - freq_avg) / ((long)afi->chunks_total + 1); + fl_avg += ((long)fl - fl_avg) / ((long)afi->chunks_total + 1); + br_avg += ((long)br - br_avg) / ((long)afi->chunks_total + 1); if (old_br != br) mp3.vbr = 1; old_br = br; @@ -381,8 +382,9 @@ static int mp3_read_info(unsigned char *map, off_t numbytes, if (!afi->chunks_total || !freq_avg || !br_avg) goto err_out; afi->chunk_table[afi->chunks_total] = numbytes - 1; - mp3.br_average = br_avg; - mp3.freq = freq_avg; + afi->bitrate = br_avg; + afi->frequency = freq_avg; + afi->channels = header_channels(&mp3.header); afi->seconds_total = (tv2ms(&total_time) + 500) / 1000; tv_divide(afi->chunks_total, &total_time, &afi->chunk_tv); PARA_DEBUG_LOG("%lu chunks, each %lums\n", afi->chunks_total, @@ -399,7 +401,7 @@ err_out: /* * Read mp3 information from audio file */ -static int mp3_get_file_info(char *map, off_t numbytes, +int mp3_get_file_info(char *map, size_t numbytes, struct audio_format_info *afi) { int ret;