diff --git a/src/scan-wav.c b/src/scan-wav.c new file mode 100644 index 00000000..ef4aba81 --- /dev/null +++ b/src/scan-wav.c @@ -0,0 +1,113 @@ +/* + * $Id$ + * + * Copyright (C) 2003 Ron Pedde (ron@pedde.com) + * + * 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-1307 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#include "err.h" +#include "mp3-scanner.h" + +#define GET_WAV_INT32(p) ((((unsigned long)((p)[3])) << 24) | \ + (((unsigned long)((p)[2])) << 16) | \ + (((unsigned long)((p)[1])) << 8) | \ + (((unsigned long)((p)[0])))) + +#define GET_WAV_INT16(p) ((((unsigned long)((p)[1])) << 8) | \ + (((unsigned long)((p)[0])))) + +/** + * Get info from the actual wav headers. Since there is no + * metainfo in .wav files (or at least know standard I + * know about), this merely gets duration, bitrate, etc. + * + * @param file file to scan + * @param pmp3 MP3FILE struct to be filled + */ +int scan_get_wavinfo(char *file, MP3FILE *pmp3) { + FILE *infile; + size_t rl; + unsigned char hdr[44]; + unsigned long chunk_data_length; + unsigned long format_data_length; + unsigned long compression_code; + unsigned long channel_count; + unsigned long sample_rate; + unsigned long sample_bit_length; + unsigned long bit_rate; + unsigned long data_length; + unsigned long sec, ms; + + DPRINTF(E_DBG,L_SCAN,"Getting WAV file info\n"); + + if(!(infile=fopen(file,"rb"))) { + DPRINTF(E_WARN,L_SCAN,"Could not open %s for reading\n",file); + return -1; + } + + fseek(infile,0,SEEK_END); + pmp3->file_size = ftell(infile); + fseek(infile,0,SEEK_SET); + + rl = fread(hdr, 1, 44, infile); + fclose(infile); + if (rl != 44) { + DPRINTF(E_WARN,L_SCAN,"Could not read wav header from %s\n",file); + return -1; + } + + if (strncmp((char*)hdr + 0, "RIFF", 4) || + strncmp((char*)hdr + 8, "WAVE", 4) || + strncmp((char*)hdr + 12, "fmt ", 4) || + strncmp((char*)hdr + 36, "data", 4)) { + DPRINTF(E_WARN,L_SCAN,"Invalid wav header in %s\n",file); + return -1; + } + + chunk_data_length = GET_WAV_INT32(hdr + 4); + format_data_length = GET_WAV_INT32(hdr + 16); + compression_code = GET_WAV_INT16(hdr + 20); + channel_count = GET_WAV_INT16(hdr + 22); + sample_rate = GET_WAV_INT32(hdr + 24); + sample_bit_length = GET_WAV_INT16(hdr + 34); + data_length = GET_WAV_INT32(hdr + 40); + + if ((format_data_length != 16) || + (compression_code != 1) || + (channel_count < 1)) { + DPRINTF(E_WARN,L_SCAN,"Invalid wav header in %s\n",file); + return -1; + } + + bit_rate = sample_rate * channel_count * ((sample_bit_length + 7) / 8) * 8; + pmp3->bitrate = bit_rate / 1000; + pmp3->samplerate = sample_rate; + sec = data_length / (bit_rate / 8); + ms = ((data_length % (bit_rate / 8)) * 1000) / (bit_rate / 8); + pmp3->song_length = (sec * 1000) + ms; + + return 0; +} +