Commit a2e63ec1 authored by Led's avatar Led

0.8.0

parent 13411a9c
......@@ -26,6 +26,10 @@ add <string file>
clear
clears the current playlist
clearerror
clear the current error message in status
(this is also accomplished by any command that starts playback)
close
close the connection with the mpd
......@@ -40,8 +44,9 @@ find <string type> <string what>
kill
kill mpd
listall
lists all available songs (without tag info)
listall <string directory>
lists all songs in _directory_ (recursively)
_directory_ is optional
load <string name>
loads the playlist _name_.m3u from the playlist directory
......@@ -88,17 +93,25 @@ search <string type> <string what>
shuffle
shuffles the current playlist
stats
display stats
artists: number of artists
albums: number of albums
songs: number of songs
uptime: daemon uptime in seconds
db_update: last db update in unix time
playtime: time length of music played
songs_played: total number of songs played
status
reports current status of player, and volume level.
volume level is printed first (0-100).
repeat status is printed second (0 or 1).
then player status, one of the following:
"stop" - player is stopped
"play <int song> <int elapsed>:<time total>"
- playing _song_ with _elapses_ seconds, and the song
is a total of _total_ seconds
"pause <int song> <int elapsed>:<tine total>"
- same as "play" but the player is currently paused
volume: (0-100).
repat: (0 or 1)
playlist: (31-bit unsigned integer, the playlist version number)
state: ("play", "stop", or "pause")
song: (current song playing/paused, playlist song number)
time: <int elapsed>:<time total> (of current playing/paused song)
error: if there is an error, returns message here
stop
stop playing
......@@ -108,3 +121,20 @@ update
volume <int change>
change volume by amount _change_
COMMAND LIST
------------
To faciliate faster adding of files, etc, you can pass a list of commands all
at once using a command list. The command list beings with:
command_list_begin
And ends with:
command_list_end
It does not execute any commands until the list has ended. The return
value is whatever the return for a list of commands is. On success
for all commands, OK is returned. If a command fails, no more commands
are executed and the appropriate ACK error is returned.
ver 0.8.0 (2003/7/6)
1) Flac support
2) Make playlist max length configurable
3) New backward compatible status (backward compatible for 0.8.0 on)
4) listall command now can take a directory as an argument
5) Buffer rewritten to use shared memory instead of sockets
6) Playlist adding done using db
7) Add sort to list, and use binary search for finding
8) New "stats" command
9) Command list (for faster adding of large batches of files)
10) Add buffered chunks before play
11) Useful error reporting to clients (part of status command)
12) Use libid3tag for reading id3 tags (more stable)
13) Non-blocking output to clients
14) Fix bug when removing items from directory
15) Fix bug when playing mono mp3's
16) Fix bug when attempting to delete files when using samba
17) Lots of other bug fixes I can't remember
ver 0.7.0 (2003/6/20)
1) use mad instead of mpg123 for mp3 decoding
2) volume support
......@@ -9,7 +28,7 @@ ver 0.6.2 (2003/6/11)
1) Buffer support for ogg
2) new config file options: "connection_timeout" and "mpg123_ignore_junk"
3) new commands: "next", "previous", and "listall"
Thanks to Nicklas Hofer for "next" and "previous" patches!
Thanks to Niklas Hofer for "next" and "previous" patches!
4) Search by filename
5) bug fix for pause when playing mp3's
......
......@@ -4,10 +4,15 @@ Requirements
------------
libao - http://www.vorbis.com/download_unix.psp
(This comes with most/all distrobutions. Make sure you have both
the ao libs and development packages for your distrobution installed.
(This comes with most/all distributions. Make sure you have both
the ao libs and development packages for your distribution installed.
For Red Hat 8.0, the neccessary packages are: libao and libao-devel)
zlib - http://www.gzip.org/zlib
(This comes with all distributions. Make sure you have bot the zlib libs
and delevelopment packages for your distribution installed. For Red hat,
the neccessary packages are: zlib and zlib-devel)
Optional
--------
......@@ -17,6 +22,9 @@ ogg and vorbis libs as well as the development packages for your
distrobution installed. For Red Hat 8.0, the neccessary packages are:
libogg, libogg-devel, libvorbis, and libvorbis-devel).
Flac - http://flac.sf.net
For Flac support, you need Flac 1.1.0 or greater.
Download
--------
......
bin_PROGRAMS = mpd
SUBDIRS = id3v1lib id3v2lib libmad
SUBDIRS = libid3tag libmad
pkgdata_DATA = mpdconf.example README INSTALL
EXTRA_DIST = COMMANDS UPGRADING $(pkgdata_DATA)
mpd_headers = buffer2array.h interface.h command.h playlist.h ls.h \
song.h list.h directory.h tables.h utils.h path.h \
tag.h player.h listen.h conf.h ogg_decode.h volume.h mp3_decode.h
song.h list.h directory.h tables.h utils.h path.h flac_decode.h \
tag.h player.h listen.h conf.h ogg_decode.h volume.h mp3_decode.h \
audio.h buffer.h stats.h myfprintf.h
mpd_SOURCES = main.c buffer2array.c interface.c command.c playlist.c ls.c \
song.c list.c directory.c tables.c utils.c path.c \
song.c list.c directory.c tables.c utils.c path.c flac_decode.c\
tag.c player.c listen.c conf.c ogg_decode.c volume.c mp3_decode.c \
$(mpd_headers)
audio.c buffer.c stats.c myfprintf.c $(mpd_headers)
MAD_LIB = libmad/.libs/libmad.a
ID3_LIB = id3v2lib/libid3v2.a id3v1lib/libid3v1.a
MAD_LIB = libmad/libmad.la
ID3_LIB = libid3tag/libid3tag.la
mpd_LDADD = $(MAD_LIB) $(ID3_LIB)
......@@ -9,9 +9,8 @@ retrieval, and playlist management can all be managed remotely.
To install MPD, see INSTALL.
MPD includes 3 libraries in the source. id3v1lib and id3v2lib are released
under the GPL and copyrighted by Samuel Abels (sam@manicsadness.com). libmad
is copyrighted by Robert Leslie (http://www.underbit.com/products/mad).
MPD includes 2 libraries in the source. libid3tag and libmad are released under
the GPL and copyrighted by Robert Leslie (http://www.underbit.com/products/mad).
MPD is released under the GNU Public License.
You should have received a copy of the GNU General Public License
......
1) store song times (possibly after playing)
2) flac support
3) seeking
4) set flags (such as BAD MP3)
2) seeking
3) set flags (such as BAD MP3)
possibly:
---------
reference songs by an id #
spawn a seperate process for db updates, that pipes updates through a socket
to the main process
Music Player Daemon (MPD) - UPGRADING
Upgrading to 0.8.0
------------------
If you have flacs, then to have them added to your list of available music,
just use "update".
Upgrading from 0.5.x to 0.6.x
-----------------------------
If you have not compiled MPD with "make ogg", then nothing is needed.
......
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
*/
#include "audio.h"
int audio_ao_driver_id;
void initAudio() {
ao_initialize();
audio_ao_driver_id = ao_default_driver_id();
}
void finishAudio() {
ao_shutdown();
}
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
*/
#ifndef AUDIO_H
#define AUDIO_H
#include <stdio.h>
#include <ao/ao.h>
extern int audio_ao_driver_id;
void initAudio();
void finishAudio();
#endif
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
*/
#include "buffer.h"
#include "command.h"
#include "conf.h"
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
int buffered_before_play;
int buffer_shmid;
Buffer * buffer_b;
void initBuffer() {
float perc;
char * test;
perc = strtod((getConf())[CONF_BUFFER_BEFORE_PLAY],&test);
if(*test!='%' || perc<0 || perc>100) {
fprintf(stderr,"buffered before play \"%s\" is not a positive percentage and less than 100 percent\n",(getConf())[CONF_BUFFER_BEFORE_PLAY]);
exit(-1);
}
buffered_before_play = (perc/100)*BUFFERED_CHUNKS;
if(buffered_before_play>BUFFERED_CHUNKS) {
buffered_before_play = BUFFERED_CHUNKS;
}
else if(buffered_before_play<0) buffered_before_play = 0;
if((buffer_shmid = shmget(IPC_PRIVATE,sizeof(Buffer),IPC_CREAT|0666))<0) {
fprintf(stderr,"%s shmget'ing\n",COMMAND_RESPOND_ERROR);
exit(-1);
}
if((buffer_b = shmat(buffer_shmid,NULL,0))<0) {
fprintf(stderr,"%s shmat'ing\n",COMMAND_RESPOND_ERROR);
exit(-1);
}
if (shmctl(buffer_shmid, IPC_RMID, 0)<0) {
fprintf(stderr,"%s shmctl'ing\n",COMMAND_RESPOND_ERROR);
exit(-1);
}
}
Buffer * getBuffer() {
return buffer_b;
}
void freeBuffer() {
shmdt(buffer_b);
}
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
*/
#ifndef BUFFER_H
#define BUFFER_H
#define CHUNK_SIZE 256
#define BUFFERED_CHUNKS 8192 /* 2 MB of buffer */
#define PLAY_SIZE 64
extern int buffered_before_play;
typedef struct _Buffer {
char chunks[BUFFERED_CHUNKS][CHUNK_SIZE];
float times[BUFFERED_CHUNKS];
int begin;
int end;
int wrap;
} Buffer;
void initBuffer();
Buffer * getBuffer();
void freeBuffer();
#endif
......@@ -103,3 +103,12 @@ int buffer2array(char * origBuffer, char *** array) {
return count;
}
void freeArgArray(char ** array, int argArrayLength) {
int i;
for(i=0;i<argArrayLength;i++) {
free(array[i]);
}
free(array);
}
......@@ -21,4 +21,6 @@
int buffer2array(char * buffer, char *** array);
void freeArgArray(char ** array, int argArrayLength);
#endif
......@@ -28,13 +28,15 @@
#define MAX_STRING_SIZE MAXPATHLEN+80
#define CONF_NUMBER_OF_PARAMS 8
#define CONF_NUMBER_OF_PARAMS 10
#define CONF_NUMBER_OF_PATHS 4
#define CONF_NUMBER_OF_REQUIRED 5
#define CONF_CONNECTION_TIMEOUT_DEFAULT "60"
#define CONF_MIXER_DEVICE_DEFAULT "/dev/mixer"
#define CONF_MAX_CONNECTIONS_DEFAULT "5"
#define CONF_CONNECTION_TIMEOUT_DEFAULT "60"
#define CONF_MIXER_DEVICE_DEFAULT "/dev/mixer"
#define CONF_MAX_CONNECTIONS_DEFAULT "5"
#define CONF_MAX_PLAYLIST_LENGTH_DEFAULT "4096"
#define CONF_BUFFER_BEFORE_PLAY_DEFAULT "25%"
char conf_strings[CONF_NUMBER_OF_PARAMS][24] = {
"port",
......@@ -44,7 +46,9 @@ char conf_strings[CONF_NUMBER_OF_PARAMS][24] = {
"error_file",
"connection_timeout",
"mixer_device",
"max_connections"
"max_connections",
"max_playlist_length",
"buffer_before_play"
};
int conf_absolutePaths[CONF_NUMBER_OF_PATHS] = {
......@@ -73,6 +77,8 @@ void initConf() {
conf_params[CONF_CONNECTION_TIMEOUT] = strdup(CONF_CONNECTION_TIMEOUT_DEFAULT);
conf_params[CONF_MIXER_DEVICE] = strdup(CONF_MIXER_DEVICE_DEFAULT);
conf_params[CONF_MAX_CONNECTIONS] = strdup(CONF_MAX_CONNECTIONS_DEFAULT);
conf_params[CONF_MAX_PLAYLIST_LENGTH] = strdup(CONF_MAX_PLAYLIST_LENGTH_DEFAULT);
conf_params[CONF_BUFFER_BEFORE_PLAY] = strdup(CONF_BUFFER_BEFORE_PLAY_DEFAULT);
}
char ** readConf(char * file) {
......
......@@ -19,14 +19,16 @@
#ifndef CONF_H
#define CONF_H
#define CONF_PORT 0
#define CONF_MUSIC_DIRECTORY 1
#define CONF_PLAYLIST_DIRECTORY 2
#define CONF_LOG_FILE 3
#define CONF_ERROR_FILE 4
#define CONF_CONNECTION_TIMEOUT 5
#define CONF_MIXER_DEVICE 6
#define CONF_MAX_CONNECTIONS 7
#define CONF_PORT 0
#define CONF_MUSIC_DIRECTORY 1
#define CONF_PLAYLIST_DIRECTORY 2
#define CONF_LOG_FILE 3
#define CONF_ERROR_FILE 4
#define CONF_CONNECTION_TIMEOUT 5
#define CONF_MIXER_DEVICE 6
#define CONF_MAX_CONNECTIONS 7
#define CONF_MAX_PLAYLIST_LENGTH 8
#define CONF_BUFFER_BEFORE_PLAY 9
/* do not free the return value, it is a static variable */
char ** readConf(char * file);
......
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
timestamp='2002-03-07'
timestamp='2001-09-07'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
......@@ -29,8 +29,7 @@ timestamp='2002-03-07'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
......@@ -118,7 +117,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
......@@ -227,7 +226,6 @@ case $basic_machine in
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dsp16xx \
......@@ -235,24 +233,25 @@ case $basic_machine in
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
| mips16 | mips64 | mips64el | mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el | mips64vr4300 \
| mips64vr4300el | mips64vr5000 | mips64vr5000el \
| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
| mipsisa32 | mipsisa64 \
| mipsisa32 \
| mn10200 | mn10300 \
| ns16k | ns32k \
| openrisc | or32 \
| openrisc \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| s390 | s390x \
| sh | sh[34] | sh[34]eb | shbe | shle \
| sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
| stormy16 | strongarm \
| tahoe | thumb | tic80 | tron \
| v850 | v850e \
| v850 \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| x86 | xscale \
| z8k)
basic_machine=$basic_machine-unknown
;;
......@@ -279,13 +278,11 @@ case $basic_machine in
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| alphapca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c54x-* \
| clipper-* | cydra-* \
| clipper-* | cray2-* | cydra-* \
| d10v-* | d30v-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | fx80-* \
......@@ -293,7 +290,7 @@ case $basic_machine in
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
......@@ -305,14 +302,14 @@ case $basic_machine in
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | v850e-* | vax-* \
| s390-* | s390x-* \
| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
| sparc-* | sparc64-* | sparc86x-* | sparclite-* \
| sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \
| t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
| v850-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
| ymp-* \
| z8k-*)
;;
......@@ -377,10 +374,6 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
......@@ -401,8 +394,16 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[cjt]90)
basic_machine=${basic_machine}-cray
os=-unicos
;;
crds | unos)
......@@ -417,14 +418,6 @@ case $basic_machine in
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
......@@ -605,6 +598,14 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux-gnu
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
......@@ -619,10 +620,6 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
......@@ -702,10 +699,6 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
......@@ -731,7 +724,7 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
pentium | p5 | k5 | k6 | nexgen)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
......@@ -740,7 +733,7 @@ case $basic_machine in
pentiumii | pentium2)
basic_machine=i686-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
......@@ -791,12 +784,6 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
......@@ -808,7 +795,7 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs | simso-wrs)
sparclite-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
......@@ -866,7 +853,7 @@ case $basic_machine in
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
sv1)
basic_machine=sv1-cray
os=-unicos
;;
......@@ -874,16 +861,8 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
t3d)
basic_machine=alpha-cray
os=-unicos
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
basic_machine=t3e-cray
os=-unicos
;;
tic54x | c54x*)
......@@ -896,10 +875,6 @@ case $basic_machine in
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
......@@ -950,13 +925,13 @@ case $basic_machine in
basic_machine=i386-pc
os=-windows32-msvcrt
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
......@@ -977,6 +952,13 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
mips)
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
;;
......@@ -999,9 +981,6 @@ case $basic_machine in
sh3 | sh4 | sh3eb | sh4eb)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
......@@ -1089,8 +1068,7 @@ case $os in
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova*)
| -os2* | -vos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
......@@ -1142,18 +1120,12 @@ case $os in
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
......@@ -1228,7 +1200,6 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
......@@ -1259,9 +1230,6 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
AC_INIT(main.c)
AM_INIT_AUTOMAKE(mpd, 0.7.0)
AC_CONFIG_SUBDIRS(libmad)
CFLAGS="-Wall"
AM_INIT_AUTOMAKE(mpd, 0.8.0)
AC_CONFIG_SUBDIRS(libid3tag libmad)
AC_PROG_CC
AC_PROG_INSTALL
......@@ -12,20 +10,45 @@ dnl MAD wants this stuff
AC_SUBST(CCAS)
AC_SUBST(CCASFLAGS)
AM_PATH_AO(LIBS="$LIBS $AO_LIBS" CFLAGS="$CFLAGS $AO_CFLAGS",AC_MSG_ERROR(Must have libao installed!!!))
AC_CHECK_HEADER(sys/soundcard.h,CFLAGS="$CFLAGS",[CFLAGS="$CFLAGS -DNO_LINUX_OSS_MIXER";AC_MSG_WARN(Soundcard headers not found -- disabling mixer)])
set -- $CFLAGS
CFLAGS="-Wall $CFLAGS"
AC_ARG_ENABLE(ogg,[ --disable-ogg disable ogg support],,enable_ogg=yes)
AC_ARG_ENABLE(flac,[ --disable-flac disable flac support],,enable_flac=yes)
XIPH_PATH_AO(LIBS="$LIBS $AO_LIBS" CFLAGS="$CFLAGS $AO_CFLAGS",AC_MSG_ERROR(Must have libao installed!!!))
AC_CHECK_HEADER(sys/soundcard.h,CFLAGS="$CFLAGS",[CFLAGS="$CFLAGS -DNO_LINUX_OSS_MIXER";AC_MSG_WARN(Soundcard headers not found -- disabling mixer)])
if test x$enable_ogg = xyes; then
AM_PATH_OGG(LIBS="$LIBS $OGG_LIBS" CFLAGS="$CFLAGS $OGG_CFLAGS",enable_ogg=no)
XIPH_PATH_OGG(LIBS="$LIBS $OGG_LIBS" CFLAGS="$CFLAGS $OGG_CFLAGS" enable_vorbistest=no,enable_ogg=no)
fi
if test x$enable_ogg = xyes; then
AM_PATH_VORBIS(LIBS="$LIBS $VORBIS_LIBS $VORBISFILE_LIBS" CFLAGS="$CFLAGS $VORBIS_CFLAGS $VORBISFILE_CFLAGS",enable_ogg=no)
XIPH_PATH_VORBIS(LIBS="$LIBS $VORBIS_LIBS $VORBISFILE_LIBS" CFLAGS="$CFLAGS $VORBIS_CFLAGS $VORBISFILE_CFLAGS",enable_ogg=no)
fi
if test x$enable_ogg = xyes; then
CFLAGS="$CFLAGS -DHAVE_OGG"
fi
AC_OUTPUT(Makefile libmad/Makefile id3v1lib/Makefile id3v2lib/Makefile)
if test x$enable_flac = xyes; then
oldcflags="$CFLAGS"
oldlibs="$LIBS"
AM_PATH_LIBFLAC(LIBS="$LIBS $LIBFLAC_LIBS" CFLAGS="$CFLAGS $LIBFLAC_CFLAGS",enable_flac=no)
fi
if test x$enable_flac = xyes; then
AC_CHECK_LIB(FLAC, FLAC__metadata_object_vorbiscomment_find_entry_from,
,[enable_flac=no;AC_MSG_WARN(You need FLAC 1.1 -- disabling flac support)])
if test x$enable_flac = xno; then
CFLAGS="$oldcflags"
LIBS="$oldlibs"
fi
fi
if test x$enable_flac = xyes; then
CFLAGS="$CFLAGS -DHAVE_FLAC"
fi
AC_OUTPUT(Makefile)
This diff is collapsed. Click to expand it.
......@@ -23,6 +23,7 @@
#include "tables.h"
#include "utils.h"
#include "path.h"
#include "myfprintf.h"
#include <string.h>
#include <sys/types.h>
......@@ -31,9 +32,6 @@
#include <unistd.h>
#include <stdio.h>
#include "list.h"
#include "song.h"
#define DIRECTORY_DIR "directory: "
#define DIRECTORY_MTIME "mtime: "
#define DIRECTORY_BEGIN "begin: "
......@@ -99,23 +97,32 @@ void freeDirectoryList(DirectoryList * directoryList) {
freeList(directoryList);
}
void removeSongFromDirectory(Directory * directory, char * shortname) {
void * song;
if(findInList(directory->songs,shortname,&song)) {
removeASongFromTables((Song *)song);
deleteFromList(directory->songs,shortname);
}
}
int updateInDirectory(Directory * directory, char * shortname, char * name) {
time_t mtime;
Song * song;
Directory * subDir;
void * song;
void * subDir;
if((mtime = isMusic(name))) {
if(0==findInList(directory->songs,shortname,(void **)&song)) {
if(0==findInList(directory->songs,shortname,&song)) {
printf("adding %s\n",name);
addToDirectory(directory,shortname,name);
}
else if(mtime>song->mtime) {
updateSongInfo(song);
else if(mtime>((Song *)song)->mtime) {
updateSongInfo((Song *)song);
}
}
else if((mtime = isDir(name))) {
if(findInList(directory->subDirectories,shortname,(void **)&subDir)) {
updateDirectory(subDir);
updateDirectory((Directory *)subDir);
}
else addSubDirectoryToDirectory(directory,shortname,name);
}
......@@ -123,15 +130,6 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) {
return 0;
}
void removeSongFromDirectory(Directory * directory, char * shortname, char * name) {
Song * song;
if(findInList(directory->songs,shortname,(void **)&song)) {
removeASongFromTables(song);
deleteFromList(directory->songs,shortname);
}
}
int removeDeletedFromDirectory(Directory * directory) {
DIR * dir;
char cwd[2];
......@@ -139,8 +137,9 @@ int removeDeletedFromDirectory(Directory * directory) {
char s[MAXPATHLEN+1];
char * dirname = directory->name;
List * entList = makeList(free);
char * name;
void * name;
ListNode * node;
ListNode * tmpNode;
cwd[0] = '.';
cwd[1] = '\0';
......@@ -164,28 +163,30 @@ int removeDeletedFromDirectory(Directory * directory) {
node = directory->subDirectories->firstNode;
while(node) {
if(findInList(entList,node->key,(void **)&name)) {
if(!isDir(name)) {
tmpNode = node->nextNode;
if(findInList(entList,node->key,&name)) {
if(!isDir((char *)name)) {
deleteFromList(directory->subDirectories,node->key);
}
}
else {
deleteFromList(directory->subDirectories,node->key);
deleteFromList(directory->subDirectories,node->key);
}
node = node->nextNode;
node = tmpNode;
}
node = directory->songs->firstNode;
while(node) {
tmpNode = node->nextNode;
if(findInList(entList,node->key,(void **)&name)) {
if(!isMusic(name)) {
removeSongFromDirectory(directory,node->key,name);
removeSongFromDirectory(directory,node->key);
}
}
else {
removeSongFromDirectory(directory,node->key,name);
removeSongFromDirectory(directory,node->key);
}
node = node->nextNode;
node = tmpNode;
}
freeList(entList);
......@@ -204,10 +205,7 @@ int updateDirectory(Directory * directory) {
cwd[1] = '\0';
if(dirname==NULL) dirname=cwd;
printf("update: %s\n",dirname);
if(isDir(dirname)>directory->mtime) {
removeDeletedFromDirectory(directory);
}
removeDeletedFromDirectory(directory);
if((dir = opendir(rmp2amp(dirname)))==NULL) return -1;
......@@ -276,32 +274,27 @@ int addToDirectory(Directory * directory, char * shortname, char * name) {
Song * song;
song = addSongToList(directory->songs,shortname,name);
if(!song) return -1;
if(song->tag) addSongToTables(song);
addSongToTables(song);
return 0;
}
return -1;
}
void initMp3Directory() {
mp3rootDirectory = newDirectory(NULL,NULL);
exploreDirectory(mp3rootDirectory);
}
void closeMp3Directory() {
freeDirectory(mp3rootDirectory);
}
Directory * findSubDirectory(Directory * directory,char * name) {
Directory * subDirectory;
void * subDirectory;
char * dup = strdup(name);
char * key;
key = strtok(dup,"/");
if(findInList(directory->subDirectories,key,(void **)&subDirectory)) {
if(findInList(directory->subDirectories,key,&subDirectory)) {
free(dup);
return subDirectory;
return (Directory *)subDirectory;
}
free(dup);
......@@ -335,7 +328,7 @@ int printDirectoryList(FILE * fp, DirectoryList * directoryList) {
while(node!=NULL) {
directory = (Directory *)node->data;
fprintf(fp,"%s%s\n",DIRECTORY_DIR,directory->name);
myfprintf(fp,"%s%s\n",DIRECTORY_DIR,directory->name);
node = node->nextNode;
}
......@@ -346,7 +339,7 @@ int printDirectoryInfo(FILE * fp,char * name) {
Directory * directory;
if((directory = getDirectory(name))==NULL) {
fprintf(fp,"%s: directory not found\n",COMMAND_RESPOND_ERROR);
myfprintf(fp,"%s: directory not found\n",COMMAND_RESPOND_ERROR);
return -1;
}
......@@ -421,13 +414,30 @@ void readDirectoryInfo(FILE * fp,Directory * directory) {
}
}
void sortDirectory(Directory * directory) {
ListNode * node = directory->subDirectories->firstNode;
Directory * subDir;
sortList(directory->subDirectories);
sortList(directory->songs);
while(node!=NULL) {
subDir = (Directory *)node->data;
sortDirectory(subDir);
node = node->nextNode;
}
}
int writeDirectoryDB() {
FILE * fp;
sortDirectory(mp3rootDirectory);
if(!(fp=fopen(directorydb,"w"))) return -1;
writeDirectoryInfo(fp,mp3rootDirectory);
fclose(fp);
return 0;
}
......@@ -439,18 +449,98 @@ int readDirectoryDB() {
readDirectoryInfo(fp,mp3rootDirectory);
fclose(fp);
sortDirectory(mp3rootDirectory);
return 0;
}
int updateMp3Directory(FILE * fp) {
if(updateDirectory(mp3rootDirectory)<0) {
fprintf(fp,"%s problems updating directory info\n",COMMAND_RESPOND_ERROR);
myfprintf(fp,"%s problems updating directory info\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(writeDirectoryDB()<0) {
fprintf(fp,"%s problems writing directory info\n",COMMAND_RESPOND_ERROR);
myfprintf(fp,"%s problems writing directory info\n",COMMAND_RESPOND_ERROR);
return -1;
}
return 0;
}
void printAllSongFilenamesInSubDirectory(FILE * fp, Directory * directory) {
ListNode * node = directory->songs->firstNode;
Song * song;
Directory * dir;
while(node!=NULL) {
song = (Song *)node->data;
myfprintf(fp,"file: %s\n",song->file);
node = node->nextNode;
}
node = directory->subDirectories->firstNode;
while(node!=NULL) {
dir = (Directory *)node->data;
printAllSongFilenamesInSubDirectory(fp,dir);
node = node->nextNode;
}
}
int printAllSongFilenamesInDirectory(FILE * fp, char * name) {
Directory * directory;
if((directory = getDirectory(name))==NULL) {
myfprintf(fp,"%s: directory not found\n",COMMAND_RESPOND_ERROR);
return -1;
}
printAllSongFilenamesInSubDirectory(fp,directory);
return 0;
}
void initMp3Directory() {
mp3rootDirectory = newDirectory(NULL,NULL);
exploreDirectory(mp3rootDirectory);
sortDirectory(mp3rootDirectory);
}
Song * getSong(char * file) {
static char * c;
static char * shortname;
static char dir[MAXPATHLEN];
static char dup[MAXPATHLEN];
static Directory * directory;
static void * song;
if(strlen(file)>MAXPATHLEN) return NULL;
dir[0] = '\0';
strcpy(dup,file);
c = strtok(dup,"/");
while(c) {
shortname = c;
c = strtok(NULL,"/");
if(c) {
strcat(dir,shortname);
strcat(dir,"/");
}
}
if(!(directory = getSubDirectory(mp3rootDirectory,dir))) return NULL;
if(!findInList(directory->songs,shortname,&song)) return NULL;
return (Song *)song;
}
time_t getDbModTime() {
time_t mtime = 0;
struct stat st;
if(stat(directorydb,&st)==0) mtime = st.st_mtime;
return mtime;
}
......@@ -19,6 +19,8 @@
#ifndef DIRECTORY_H
#define DIRECTORY_H
#include "song.h"
#include <stdio.h>
#include <sys/param.h>
......@@ -38,4 +40,10 @@ size_t getDirectoryLine(char ** buffer, int * size, FILE * fp);
int updateMp3Directory(FILE * fp);
int printAllSongFilenamesInDirectory(FILE * fp, char * dirname);
Song * getSong(char * file);
time_t getDbModTime();
#endif
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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_FLAC
#include "flac_decode.h"
#include "player.h"
#include "command.h"
#include "utils.h"
#include "audio.h"
#include "buffer.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <ao/ao.h>
#include <FLAC/file_decoder.h>
#include <FLAC/metadata.h>
#define INPUT_BUFFER_SIZE 80
#define CHECK_INPUT_FREQ 300 /* about once very 0.1 seconds */
#define TIME_TELL_INTERVAL 0.2
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
typedef struct {
unsigned char chunk[CHUNK_SIZE];
int chunk_length;
float time;
Buffer * cb;
ao_sample_format * format;
} FlacData;
int flac_decode_pid = 0;
int flac_decode_done = 0;
ao_device * flac_device = NULL;
void flacPlayfile(const char * file, Buffer * cb, ao_sample_format * format);
void flacError(const FLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *);
void flacMetadata(const FLAC__FileDecoder *, const FLAC__StreamMetadata *, void *);
FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const buf[], void *);
void flacPlayFile(const char *file, Buffer * cb, ao_sample_format * format)
{
FLAC__FileDecoder * flacDec;
FlacData data;
data.chunk_length = 0;
data.time = 0;
data.cb = cb;
data.format = format;
flacDec = FLAC__file_decoder_new();
FLAC__file_decoder_set_md5_checking(flacDec,TRUE);
FLAC__file_decoder_set_filename(flacDec,file);
FLAC__file_decoder_set_write_callback(flacDec,flacWrite);
FLAC__file_decoder_set_metadata_callback(flacDec,flacMetadata);
FLAC__file_decoder_set_error_callback(flacDec,flacError);
FLAC__file_decoder_set_client_data(flacDec, (void *)&data);
FLAC__file_decoder_init(flacDec);
FLAC__file_decoder_process_until_end_of_file(flacDec);
FLAC__file_decoder_finish(flacDec);
FLAC__file_decoder_delete(flacDec);
}
void flacError(const FLAC__FileDecoder *dec, FLAC__StreamDecoderErrorStatus status, void *data) {
}
void flacMetadata(const FLAC__FileDecoder *dec, const FLAC__StreamMetadata *meta, void *data) {
}
void flacSendChunk(FlacData * data) {
while(data->cb->begin==data->cb->end && data->cb->wrap)
usleep(100);
memcpy(data->cb->chunks[data->cb->end],data->chunk,CHUNK_SIZE);
data->cb->times[data->cb->end] = data->time;
data->cb->end++;
if(data->cb->end>=BUFFERED_CHUNKS) {
data->cb->end = 0;
data->cb->wrap = 1;
}
}
FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__FileDecoder *dec, const FLAC__Frame *frame, const FLAC__int32 * const buf[], void * vdata) {
FlacData * data = (FlacData *)vdata;
uint_32 dataSize = frame->header.blocksize * frame->header.channels
* (data->format->bits / 8);
uint_32 samples = frame->header.blocksize;
uint_16 ldb[samples*frame->header.channels];
int c_samp, c_chan, d_samp;
unsigned char * ldbuc = (unsigned char *)ldb;
for(c_samp = d_samp = 0; c_samp < frame->header.blocksize; c_samp++) {
for(c_chan = 0; c_chan < frame->header.channels;
c_chan++, d_samp++) {
ldb[d_samp] = buf[c_chan][c_samp];
}
}
data->time+=((float)samples)/frame->header.sample_rate;
while(dataSize>0) {
if(data->chunk_length>=CHUNK_SIZE) {
flacSendChunk(data);
data->chunk_length = 0;
}
data->chunk[data->chunk_length++] = *(ldbuc++);
dataSize--;
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
int flac_getAoDataAndTime(char * file, ao_sample_format * format, float * time) {
FLAC__Metadata_SimpleIterator * it;
FLAC__StreamMetadata * block = NULL;
int found = 0;
int ret = -1;
it = FLAC__metadata_simple_iterator_new();
if(!FLAC__metadata_simple_iterator_init(it,file,1,0)) {
FLAC__metadata_simple_iterator_delete(it);
return -1;
}
do {
if(block) FLAC__metadata_object_delete(block);
block = FLAC__metadata_simple_iterator_get_block(it);
if(block->type == FLAC__METADATA_TYPE_STREAMINFO) found=1;
} while(!found && FLAC__metadata_simple_iterator_next(it));
if(found) {
format->bits = block->data.stream_info.bits_per_sample;
format->rate = block->data.stream_info.sample_rate;
format->channels = block->data.stream_info.channels;
format->byte_format = AO_FMT_LITTLE;
*time = ((float)block->data.stream_info.total_samples)/format->rate;
ret = 0;
}
if(block) FLAC__metadata_object_delete(block);
FLAC__metadata_simple_iterator_delete(it);
return ret;
}
void flac_decode_parentSigHandler(int sig) {
if(sig==SIGCHLD) {
if(flac_decode_pid==wait3(NULL,WNOHANG,NULL)) {
flac_decode_pid = 0;
flac_decode_done = 1;
}
}
if(sig==SIGTERM) {
int pid = flac_decode_pid;
if(pid>0) kill(pid,SIGTERM);
if(flac_device) ao_close(flac_device);
exit(0);
}
}
/* flac_decode w/ buffering
* this will fork another process
* child process does decoding
* parent process does buffering && playing audio
*/
int flac_decode(char * file, FILE * in, FILE * out) {
Buffer * cb;
ao_sample_format format;
float total_time;
struct sigaction sa;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
cb = getBuffer();
cb->begin = 0;
cb->end = 0;
cb->wrap = 0;
if(flac_getAoDataAndTime(file,&format,&total_time)<0) {
fprintf(stderr,"%s \"%s\" doesn't seem to be a flac\n",COMMAND_RESPOND_ERROR,file);
return PLAYER_EXIT_ERROR_FILE;
}
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE,&sa,NULL);
sa.sa_handler = flac_decode_parentSigHandler;
sigaction(SIGCHLD,&sa,NULL);
sa.sa_handler = flac_decode_parentSigHandler;
sigaction(SIGTERM,&sa,NULL);
fflush(NULL);
flac_decode_pid = fork();
if(flac_decode_pid==0) {
/* CHILD */
fclose(in);
fclose(out);
flacPlayFile(file,cb,&format);
while(cb->begin==cb->end && cb->wrap) usleep(100);
cb->times[cb->end] = -1;
cb->end++;
if(cb->end>=BUFFERED_CHUNKS) {
cb->end = 0;
cb->wrap = 1;
}
exit(0);
/* END OF CHILD */
}
else if(flac_decode_pid<0) {
fprintf(stderr,"%s flac_decode Problems fork'ing\n",COMMAND_RESPOND_ERROR);
return PLAYER_EXIT_ERROR_SYSTEM;
}
{
/* PARENT */
float elapsed = 0;
float last_tell = 0;
int pause = 0;
char input[INPUT_BUFFER_SIZE+1];
int playsPerChunk = CHUNK_SIZE/PLAY_SIZE;
int currentPlayChunk = 0;
int quit = 0;
fd_set fds;
struct timeval tv;
int checkInput = 0;
int pid;
tv.tv_sec = 0;
tv.tv_usec = 0;
initAudio();
flac_device = ao_open_live(audio_ao_driver_id,&format,NULL);
if(flac_device == NULL) {
fprintf(stderr, "%s Error opening device.\n",PLAYER_ERROR);
fflush(stderr);
pid = flac_decode_pid;
if(pid>0) kill(pid,SIGTERM);
return PLAYER_EXIT_ERROR_AUDIO;
}
fprintf(out,"%s\n",PLAYER_START);
fprintf(out,"%s %f %f\n",PLAYER_TIME,last_tell,total_time);
fflush(out);
while(flac_decode_pid>0 && !cb->wrap && cb->end-cb->begin<buffered_before_play) {
usleep(1000);
}
while(!quit) {
if((cb->begin!=cb->end || cb->wrap) && !pause) {
if(currentPlayChunk==0) elapsed = cb->times[cb->begin];
ao_play(flac_device,cb->chunks[cb->begin]+currentPlayChunk*PLAY_SIZE,PLAY_SIZE);
currentPlayChunk++;
if(currentPlayChunk>=playsPerChunk) {
currentPlayChunk=0;
cb->begin++;
if(cb->times[cb->begin]<0) quit = 1;
if(cb->begin>=BUFFERED_CHUNKS) {
cb->begin = 0;
cb->wrap = 0;
}
}
if(elapsed-last_tell>=TIME_TELL_INTERVAL) {
last_tell = elapsed;
fprintf(out,"%s %f %f\n",PLAYER_TIME,last_tell,total_time);
fflush(out);
}
}
else if(flac_decode_pid<=0 && (cb->begin==cb->end && !cb->wrap)) {
quit = 1;
}
else usleep(200);
if(pause || checkInput%CHECK_INPUT_FREQ==0) {
FD_ZERO(&fds);
FD_SET(fileno(in),&fds);
fflush(in);
if(select(fileno(in)+1,&fds,NULL,NULL,&tv)) {
myFgets(input,INPUT_BUFFER_SIZE,in);
if(strcasecmp(PLAYER_PAUSE,input)==0) {
fprintf(out,"%s\n",PLAYER_PAUSE_GOT);
fflush(out);
pause = !pause;
}
}
checkInput = 1;
}
checkInput++;
}
pid = flac_decode_pid;
if(pid>0) kill(pid,SIGTERM);
ao_close(flac_device);
finishAudio();
/* END OF PARENT */
}
return 0;
}
#endif
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
*/
#ifndef FLAC_DECODE_H
#define FLAC_DECODE_H
#include <stdio.h>
int flac_decode(char * file, FILE * in, FILE * out);
#endif
noinst_LIBRARIES=libid3v1.a
libid3v1_a_headers = lib_id3v1.h genre.h
libid3v1_a_SOURCES = lib_id3v1.c $(libid3v1_a_headers)
# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@
AS = @AS@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EXEEXT = @EXEEXT@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
VORBISFILE_LIBS = @VORBISFILE_LIBS@
VORBIS_CFLAGS = @VORBIS_CFLAGS@
VORBIS_LIBS = @VORBIS_LIBS@
noinst_LIBRARIES = libid3v1.a
libid3v1_a_headers = lib_id3v1.h genre.h
libid3v1_a_SOURCES = lib_id3v1.c $(libid3v1_a_headers)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libid3v1_a_LIBADD =
libid3v1_a_OBJECTS = lib_id3v1.$(OBJEXT)
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = README COPYING Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libid3v1_a_SOURCES)
OBJECTS = $(libid3v1_a_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps id3v1lib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-noinstLIBRARIES:
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
distclean-noinstLIBRARIES:
maintainer-clean-noinstLIBRARIES:
.c.o:
$(COMPILE) -c $<
# FIXME: We should only use cygpath when building on Windows,
# and only if it is available.
.c.obj:
$(COMPILE) -c `cygpath -w $<`
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libid3v1.a: $(libid3v1_a_OBJECTS) $(libid3v1_a_DEPENDENCIES)
-rm -f libid3v1.a
$(AR) cru libid3v1.a $(libid3v1_a_OBJECTS) $(libid3v1_a_LIBADD)
$(RANLIB) libid3v1.a
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = id3v1lib
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LIBRARIES)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-tags \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \
clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-libtool distclean-tags distclean-generic \
clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
This library was written by Samuel Abels (sam@manicsadness.com).
If you have any questions, feel free to contact me, or visit the project homepage at
http://software.manicsadness.com
----------------
The library is very easy to use.
It is meant to be compiled directly into your project.
Example:
#include "genre.h"
#include "lib_id3v1.h"
main()
{
id3Tag tag;
strcpy (tag.artist, "Myartist");
strcpy (tag.album, "Myalbum");
strcpy (tag.title, "Mysong");
strcpy (tag.track, "12");
strcpy (tag.year, "2002");
strcpy (tag.comment, "Mycomment");
strcpy (tag.genre, genre[14]);
set_id3v1tag(&tag, "/home/sam/myfile.mp3");
}
If you need more info, look into the header file, it's really simple.
/* the id3v1 library.
* (c)2002 by Samuel Abels (sam@manicsadness.com)
* This project's homepage is: http://software.manicsadness.com/cantus
*
* This library is designed for easyest possible access to id3 V1 tags.
*
* 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
*/
#ifndef GENRE_H
#define GENRE_H
#define NUM_GENRES 150
char *genre[]={
/*1*/ "Blues",
/*2*/ "Classic Rock",
/*3*/ "Country",
/*4*/ "Dance",
/*5*/ "Disco",
/*6*/ "Funk",
/*7*/ "Grunge",
/*8*/ "Hip-Hop",
/*9*/ "Jazz",
/*10*/ "Metal",
/*11*/ "New Age",
/*12*/ "Oldies",
/*13*/ "Other",
/*14*/ "Pop",
/*15*/ "R&B",
/*16*/ "Rap",
/*17*/ "Reggae",
/*18*/ "Rock",
/*19*/ "Techno",
/*20*/ "Industrial",
/*21*/ "Alternative",
/*22*/ "Ska",
/*23*/ "Death Metal",
/*24*/ "Pranks",
/*25*/ "Soundtrack",
/*26*/ "Euro-Techno",
/*27*/ "Ambient",
/*28*/ "Trip-Hop",
/*29*/ "Vocal",
/*30*/ "Jazz+Funk",
/*31*/ "Fusion",
/*32*/ "Trance",
/*33*/ "Classical",
/*34*/ "Instrumental",
/*35*/ "Acid",
/*36*/ "House",
/*37*/ "Game",
/*38*/ "Sound Clip",
/*39*/ "Gospel",
/*40*/ "Noise",
/*41*/ "AlternRock",
/*42*/ "Bass",
/*43*/ "Soul",
/*44*/ "Punk",
/*45*/ "Space",
/*46*/ "Meditative",
/*47*/ "Instrumental Pop",
/*48*/ "Instrumental Rock",
/*49*/ "Ethnic",
/*50*/ "Gothic",
/*51*/ "Darkwave",
/*52*/ "Techno-Industrial",
/*53*/ "Electronic",
/*54*/ "Pop-Folk",
/*55*/ "Eurodance",
/*56*/ "Dream",
/*57*/ "Southern Rock",
/*58*/ "Comedy",
/*59*/ "Cult",
/*60*/ "Gangsta",
/*61*/ "Top 40",
/*62*/ "Christian Rap",
/*63*/ "Pop/Funk",
/*64*/ "Jungle",
/*65*/ "Native American",
/*66*/ "Cabaret",
/*67*/ "New Wave",
/*68*/ "Psychadelic",
/*69*/ "Rave",
/*70*/ "Showtunes",
/*71*/ "Trailer",
/*72*/ "Lo-Fi",
/*73*/ "Tribal",
/*74*/ "Acid Punk",
/*75*/ "Acid Jazz",
/*76*/ "Polka",
/*77*/ "Retro",
/*78*/ "Musical",
/*79*/ "Rock & Roll",
/*80*/ "Hard Rock",
// WinAmp extensions:
/*81*/ "Folk",
/*82*/ "Folk-Rock",
/*83*/ "National Folk",
/*84*/ "Swing",
/*85*/ "Fast Fusion",
/*86*/ "Bebob",
/*87*/ "Latin",
/*88*/ "Revival",
/*89*/ "Celtic",
/*90*/ "Bluegrass",
/*91*/ "Avantgarde",
/*92*/ "Gothic Rock",
/*93*/ "Progressive Rock",
/*94*/ "Psychedelic Rock",
/*95*/ "Symphonic Rock",
/*96*/ "Slow Rock",
/*97*/ "Big Band",
/*98*/ "Chorus",
/*99*/ "Easy Listening",
/*100*/ "Acoustic",
/*101*/ "Humour",
/*102*/ "Speech",
/*103*/ "Chanson",
/*104*/ "Opera",
/*105*/ "Chamber Music",
/*106*/ "Sonata",
/*107*/ "Symphony",
/*108*/ "Booty Bass",
/*109*/ "Primus",
/*110*/ "Porn Groove",
/*111*/ "Satire",
/*112*/ "Slow Jam",
/*113*/ "Club",
/*114*/ "Tango",
/*115*/ "Samba",
/*116*/ "Folklore",
/*117*/ "Ballad",
/*118*/ "Power Ballad",
/*119*/ "Rhythmic Soul",
/*120*/ "Freestyle",
/*121*/ "Duet",
/*122*/ "Punk Rock",
/*123*/ "Drum Solo",
/*124*/ "A capella",
/*125*/ "Euro-House",
/*126*/ "Dance Hall",
/*127*/ "Goa",
/*128*/ "Drum & Bass",
/*129*/ "Club-House",
/*130*/ "Hardcore",
/*131*/ "Terror",
/*132*/ "Indie",
/*133*/ "BritPop",
/*134*/ "Negerpunk",
/*135*/ "Polsk Punk",
/*136*/ "Beat",
/*137*/ "Christian Gansta Rap",
/*138*/ "Heavy Metal",
/*139*/ "Black Metal",
/*140*/ "Crossover",
/*141*/ "Contemporary Christian",
/*142*/ "Christian Rock",
/*143*/ "Merengue",
/*144*/ "Salsa",
/*145*/ "Thrash Metal",
/*146*/ "Anime",
/*147*/ "Jpop",
/*148*/ "Synthpop"
};
#endif
/* the id3v1 library.
* (c)2002 by Samuel Abels (sam@manicsadness.com)
* This project's homepage is: http://software.manicsadness.com/cantus
*
* This library is designed for easyest possible access to id3 V1 tags.
*
* 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
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include "lib_id3v1.h"
#include "genre.h"
/*
* Purpose: Reads the ID3 tag from a file.
* Parameters: tag - The structure to store the tag in, filename - The name of the file to operate on.
* Returns:
* 0 if successful,
* 1 if an error occured when opening the file
* 2 if error while reading tag.
* 3 if no TAG found.
*/
int get_id3v1_tag(id3Tag *tag, char *filename)
{
FILE *mp3file;
char *buffer = malloc(2048);
id3v1Tag *v1 = malloc(sizeof(id3v1Tag));
short int foundtag = FALSE;
int i = -1;
memset(tag, 0, sizeof(id3Tag));
memset(v1, 0, sizeof(id3v1Tag));
memset(buffer, 0, 2048);
mp3file = fopen(filename, "rb");
if (!mp3file)
return 1;
// read the last 200 bytes of the file.
// in most cases, the last 128 bytes would be enough, but some buggy tags, again...
fseek(mp3file, -200, SEEK_END);
if( !fread(buffer, 1, 400, mp3file) )
{
free(buffer);
free(v1);
fclose(mp3file);
return 2;
}
fclose(mp3file);
// parse through the raw data, if a "TAG" sign is found, we copy the raw data to a struct.
i = -1;
while( ++i <= (200-128) )
{
if( (*(buffer + i + 0) == 'T')
&& (*(buffer + i + 1) == 'A')
&& (*(buffer + i + 2) == 'G') )
{
memcpy(v1, buffer + i + 3, 125);
foundtag = TRUE;
break;
}
}
free(buffer);
if(!foundtag)
{
free(v1);
return 3;
}
strncpy(tag->title, v1->title, 30);
strncpy(tag->artist, v1->artist, 30);
strncpy(tag->album, v1->album, 30);
strncpy(tag->year, v1->year, 4);
if(v1->comment[28]=='\0' && v1->comment[29]!='\0')
{
strncpy(tag->comment, v1->comment, 28);
snprintf(tag->track, 3, "%i", v1->comment[29]);
tag->comment[29] = '\0';
}
else
{
strncpy(tag->comment, v1->comment, 30);
tag->comment[30] = '\0';
}
if( v1->genre > 148 )
strncpy(tag->genre, genre[12], 511);
else
strncpy(tag->genre, genre[v1->genre], 511);
free(v1);
return 0;
}
/*
* Purpose: Writes the ID3 tag to the file.
* Parameters: tag - The tag to write, filename - The name of the file to operate on.
* Returns:
* 0 if successful,
* 1 if an error occured when opening the file for reading
* 2 if error while reading whole file.
* 3 if an error occured while writing the whole file
* 4 if error while opening file for tagadding.
* 5 if error while writing the tag.
*/
int set_id3v1_tag(id3Tag *tag, char *filename)
{
FILE *mp3file;
id3v1Tag *v1;
int i = 0;
del_id3v1_tag(filename);
// Prepare users data for writing
v1 = malloc(sizeof(id3v1Tag));
memcpy(v1->title, tag->title, 30);
memcpy(v1->artist, tag->artist, 30);
memcpy(v1->album, tag->album, 30);
memcpy(v1->year, tag->year, 4);
if(tag->track)
{
memcpy(v1->comment, tag->comment, 28);
v1->comment[28]='\0';
*(v1->comment+29) = atoi(tag->track);
}
else
{
memcpy(v1->comment, tag->comment, 30);
}
// Find the genre number
i = -1;
while(genre[++i])
{
if(strcmp(genre[i], tag->genre) == 0)
break;
}
// ...or set the genre to "other"
if(!genre[i])
i = 12;
v1->genre = i;
mp3file = fopen(filename, "r+b");
if (!mp3file)
{
free(v1);
return 4;
}
// now add the new tag
fseek(mp3file, 0, SEEK_END);
fputc('T', mp3file);
fputc('A', mp3file);
fputc('G', mp3file);
if (!fwrite(v1, 1, sizeof(id3v1Tag), mp3file))
{
free(v1);
fclose(mp3file);
return 5;
}
fclose(mp3file);
free(v1);
return 0;
}
/*
* Name says it all.
* Returns:
* 0 if successful,
* 1 if an error occured when opening the file
* 2 if error while reading file.
* 3 if no TAG found.
*/
int del_id3v1_tag(char *filename)
{
FILE *mp3stream;
int mp3file;
long i = 0, len;
char buffer[400];
// Find length of the file
mp3stream = fopen(filename, "r+b");
if(!mp3stream)
return 1;
fseek(mp3stream, 0, SEEK_END);
len = ftell(mp3stream);
fclose(mp3stream);
// Open file for writing
mp3file = open(filename, O_RDWR);
if(mp3file == -1)
return 1;
// if there is an existing tag, delete it.
memset (buffer, 0, 400);
// read the last 400 bytes of the file.
// in most cases, the last 128 bytes would be enough, but some buggy tags, again...
lseek (mp3file, -400L, SEEK_END);
if ( read(mp3file, buffer, 400) < 400 )
{
close(mp3file);
return 2;
}
i = -1;
while ( ++i <= 400 )
{
if( buffer[i] == 'T'
&& buffer[i + 1] == 'A'
&& buffer[i + 2] == 'G' )
{
ftruncate (mp3file, len - (400 - i) );
break;
}
}
close(mp3file);
return 0;
}
/* the id3v1 library.
* (c)2002 by Samuel Abels (sam@manicsadness.com)
* This project's homepage is: http://software.manicsadness.com/cantus
*
* This library is designed for easyest possible access to id3 V1 tags.
*
* 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
*/
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef id3Tag_def
#define id3Tag_def
typedef struct id3Tag_s
{
char title[1024];
char artist[1024];
char album[1024];
char year[5];
char comment[1024];
char track[10];
char genre[512];
unsigned int size;
short int has_footer;
} id3Tag;
typedef struct id3v1Tag_s
{
char title[30];
char artist[30];
char album[30];
char year[4];
char comment[30];
unsigned char genre;
} id3v1Tag;
#endif
int get_id3v1_tag(id3Tag *tag, char *filename);
int set_id3v1_tag(id3Tag *tag, char *filename);
int del_id3v1_tag(char *filename);
noinst_LIBRARIES=libid3v2.a
libid3v2_a_headers = charset.h lib_id3v2.2.h lib_id3v2.3.h genre.h
libid3v2_a_SOURCES = charset.c lib_id3v2.2.c lib_id3v2.3.c $(libid3v2_a_headers)
# Makefile.in generated automatically by automake 1.4-p4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
AO_CFLAGS = @AO_CFLAGS@
AO_LIBS = @AO_LIBS@
AS = @AS@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EXEEXT = @EXEEXT@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OGG_CFLAGS = @OGG_CFLAGS@
OGG_LIBS = @OGG_LIBS@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
VORBISENC_LIBS = @VORBISENC_LIBS@
VORBISFILE_LIBS = @VORBISFILE_LIBS@
VORBIS_CFLAGS = @VORBIS_CFLAGS@
VORBIS_LIBS = @VORBIS_LIBS@
noinst_LIBRARIES = libid3v2.a
libid3v2_a_headers = charset.h lib_id3v2.2.h lib_id3v2.3.h genre.h
libid3v2_a_SOURCES = charset.c lib_id3v2.2.c lib_id3v2.3.c $(libid3v2_a_headers)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libid3v2_a_LIBADD =
libid3v2_a_OBJECTS = charset.$(OBJEXT) lib_id3v2.2.$(OBJEXT) \
lib_id3v2.3.$(OBJEXT)
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = README COPYING Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
SOURCES = $(libid3v2_a_SOURCES)
OBJECTS = $(libid3v2_a_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps id3v2lib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-noinstLIBRARIES:
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
distclean-noinstLIBRARIES:
maintainer-clean-noinstLIBRARIES:
.c.o:
$(COMPILE) -c $<
# FIXME: We should only use cygpath when building on Windows,
# and only if it is available.
.c.obj:
$(COMPILE) -c `cygpath -w $<`
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libid3v2.a: $(libid3v2_a_OBJECTS) $(libid3v2_a_DEPENDENCIES)
-rm -f libid3v2.a
$(AR) cru libid3v2.a $(libid3v2_a_OBJECTS) $(libid3v2_a_LIBADD)
$(RANLIB) libid3v2.a
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = id3v2lib
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(LIBRARIES)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-tags \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \
clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-libtool distclean-tags distclean-generic \
clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
This library was written by Samuel Abels (sam@manicsadness.com).
The charset conversion were taken from EasyTag, but he took it from XMMS.
If you have any questions, feel free to contact me, or visit the project homepage at
http://software.manicsadness.com
Authors
------------
Samuel Abels (sam@manicsadness.com)
Patches
------------
Matt McClure (mlm@aya.yale.edu)
----------------
The library is very easy to use.
It is meant to be compiled directly into your project.
Example:
#include "genre.h"
#include "lib_id3v1.h"
main()
{
id3Tag tag;
strcpy (tag.artist, "Myartist");
strcpy (tag.album, "Myalbum");
strcpy (tag.title, "Mysong");
strcpy (tag.track, "12");
strcpy (tag.year, "2002");
strcpy (tag.comment, "Mycomment");
strcpy (tag.genre, "Mygenre");
set_id3v2tag(&tag, "/home/sam/myfile.mp3");
}
If you need more info, look into the header file, it's really simple.
/* charset.h - 2001/12/04 */
/*
* EasyTAG - Tag editor for MP3 and OGG files
* Copyright (C) 2000-2002 Jerome Couderc <j.couderc@ifrance.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.
*/
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
/*
* Standard gettext macros.
*/
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(String) gettext (String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define textdomain(String) (String)
# define gettext(String) (String)
# define dgettext(Domain,Message) (Message)
# define dcgettext(Domain,Message,Type) (Message)
# define bindtextdomain(Domain,Directory) (Domain)
# define _(String) (String)
# define N_(String) (String)
#endif
#ifndef DLL_H
#define DLL_H
typedef struct DLL_s
{
void *prev;
void *data;
void *next;
} DLL;
#endif
#ifndef __CHARSET_H__
#define __CHARSET_H__
/***************
* Declaration *
***************/
typedef struct {
char *charset_title;
char *charset_name;
} CharsetInfo;
/* translated charset titles */
extern const CharsetInfo charset_trans_array[];
/**************
* Prototypes *
**************/
//static gchar* get_current_charset (void);
/* Used for ogg tags */
char* convert_to_utf8 (const char *string);
char* convert_from_utf8 (const char *string);
char* convert_from_file_to_user (const char *string);
char* convert_from_user_to_file (const char *string);
DLL *Charset_Create_List (void);
char *Charset_Get_Name_From_Title (char *charset_title);
char *Charset_Get_Title_From_Name (char *charset_name);
short int test_conversion_charset (char *from, char *to);
#endif /* __CHARSET_H__ */
/* the id3v1 library.
* (c)2002 by Samuel Abels (sam@manicsadness.com)
* This project's homepage is: http://software.manicsadness.com/cantus
*
* This library is designed for easyest possible access to id3 V1 tags.
*
* 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
*/
#ifndef GENRE_H
#define GENRE_H
#define NUM_GENRES 150
char *genre[]={
/*1*/ "Blues",
/*2*/ "Classic Rock",
/*3*/ "Country",
/*4*/ "Dance",
/*5*/ "Disco",
/*6*/ "Funk",
/*7*/ "Grunge",
/*8*/ "Hip-Hop",
/*9*/ "Jazz",
/*10*/ "Metal",
/*11*/ "New Age",
/*12*/ "Oldies",
/*13*/ "Other",
/*14*/ "Pop",
/*15*/ "R&B",
/*16*/ "Rap",
/*17*/ "Reggae",
/*18*/ "Rock",
/*19*/ "Techno",
/*20*/ "Industrial",
/*21*/ "Alternative",
/*22*/ "Ska",
/*23*/ "Death Metal",
/*24*/ "Pranks",
/*25*/ "Soundtrack",
/*26*/ "Euro-Techno",
/*27*/ "Ambient",
/*28*/ "Trip-Hop",
/*29*/ "Vocal",
/*30*/ "Jazz+Funk",
/*31*/ "Fusion",
/*32*/ "Trance",
/*33*/ "Classical",
/*34*/ "Instrumental",
/*35*/ "Acid",
/*36*/ "House",
/*37*/ "Game",
/*38*/ "Sound Clip",
/*39*/ "Gospel",
/*40*/ "Noise",
/*41*/ "AlternRock",
/*42*/ "Bass",
/*43*/ "Soul",
/*44*/ "Punk",
/*45*/ "Space",
/*46*/ "Meditative",
/*47*/ "Instrumental Pop",
/*48*/ "Instrumental Rock",
/*49*/ "Ethnic",
/*50*/ "Gothic",
/*51*/ "Darkwave",
/*52*/ "Techno-Industrial",
/*53*/ "Electronic",
/*54*/ "Pop-Folk",
/*55*/ "Eurodance",
/*56*/ "Dream",
/*57*/ "Southern Rock",
/*58*/ "Comedy",
/*59*/ "Cult",
/*60*/ "Gangsta",
/*61*/ "Top 40",
/*62*/ "Christian Rap",
/*63*/ "Pop/Funk",
/*64*/ "Jungle",
/*65*/ "Native American",
/*66*/ "Cabaret",
/*67*/ "New Wave",
/*68*/ "Psychadelic",
/*69*/ "Rave",
/*70*/ "Showtunes",
/*71*/ "Trailer",
/*72*/ "Lo-Fi",
/*73*/ "Tribal",
/*74*/ "Acid Punk",
/*75*/ "Acid Jazz",
/*76*/ "Polka",
/*77*/ "Retro",
/*78*/ "Musical",
/*79*/ "Rock & Roll",
/*80*/ "Hard Rock",
// WinAmp extensions:
/*81*/ "Folk",
/*82*/ "Folk-Rock",
/*83*/ "National Folk",
/*84*/ "Swing",
/*85*/ "Fast Fusion",
/*86*/ "Bebob",
/*87*/ "Latin",
/*88*/ "Revival",
/*89*/ "Celtic",
/*90*/ "Bluegrass",
/*91*/ "Avantgarde",
/*92*/ "Gothic Rock",
/*93*/ "Progressive Rock",
/*94*/ "Psychedelic Rock",
/*95*/ "Symphonic Rock",
/*96*/ "Slow Rock",
/*97*/ "Big Band",
/*98*/ "Chorus",
/*99*/ "Easy Listening",
/*100*/ "Acoustic",
/*101*/ "Humour",
/*102*/ "Speech",
/*103*/ "Chanson",
/*104*/ "Opera",
/*105*/ "Chamber Music",
/*106*/ "Sonata",
/*107*/ "Symphony",
/*108*/ "Booty Bass",
/*109*/ "Primus",
/*110*/ "Porn Groove",
/*111*/ "Satire",
/*112*/ "Slow Jam",
/*113*/ "Club",
/*114*/ "Tango",
/*115*/ "Samba",
/*116*/ "Folklore",
/*117*/ "Ballad",
/*118*/ "Power Ballad",
/*119*/ "Rhythmic Soul",
/*120*/ "Freestyle",
/*121*/ "Duet",
/*122*/ "Punk Rock",
/*123*/ "Drum Solo",
/*124*/ "A capella",
/*125*/ "Euro-House",
/*126*/ "Dance Hall",
/*127*/ "Goa",
/*128*/ "Drum & Bass",
/*129*/ "Club-House",
/*130*/ "Hardcore",
/*131*/ "Terror",
/*132*/ "Indie",
/*133*/ "BritPop",
/*134*/ "Negerpunk",
/*135*/ "Polsk Punk",
/*136*/ "Beat",
/*137*/ "Christian Gansta Rap",
/*138*/ "Heavy Metal",
/*139*/ "Black Metal",
/*140*/ "Crossover",
/*141*/ "Contemporary Christian",
/*142*/ "Christian Rock",
/*143*/ "Merengue",
/*144*/ "Salsa",
/*145*/ "Thrash Metal",
/*146*/ "Anime",
/*147*/ "Jpop",
/*148*/ "Synthpop"
};
#endif
/* the id3v2.2 library.
* (c)2002 by Samuel Abels (sam@manicsadness.com) and Warren Dukes
* This project's homepage is: http://software.manicsadness.com/cantus
*
* This library is designed for easyest possible access to id3 V2 tags.
*
* 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
*/
#ifndef DLL_H
#define DLL_H
typedef struct DLL_s
{
void *prev;
void *data;
void *next;
} DLL;
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef id3Tag_def
#define id3Tag_def
typedef struct id3Tag_s
{
char title[1024];
char artist[1024];
char album[1024];
char year[5];
char comment[1024];
char track[10];
char genre[512];
unsigned int size;
short int has_footer;
} id3Tag;
typedef struct id3v22Tag_s
{
// header
int tag_size;
short int unsync;
short int is_experimental;
//extheader
int padding_size;
short int crc_data_present;
char crc_data[4];
// frames
DLL *frames;
} id3v22Tag;
typedef struct id3v22Frame_s
{
unsigned char id[3];
int datasize;
short int tagalter;
short int filealter;
short int readonly;
short int compression;
short int encryption;
short int grouping;
char *data;
} id3v22Frame;
#endif
extern int get_id3v22_tag(id3Tag *tag, char *filename);
extern int set_id3v22_tag(id3Tag *tag, char *filename);
extern int del_id3v22_tag(char *filename);
/* the id3v2.3 library.
* (c)2002 by Samuel Abels (sam@manicsadness.com)
* This project's homepage is: http://software.manicsadness.com/cantus
*
* This library is designed for easyest possible access to id3 V2 tags.
*
* 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
*/
#ifndef DLL_H
#define DLL_H
typedef struct DLL_s
{
void *prev;
void *data;
void *next;
} DLL;
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef id3Tag_def
#define id3Tag_def
typedef struct id3Tag_s
{
char title[1024];
char artist[1024];
char album[1024];
char year[5];
char comment[1024];
char track[10];
char genre[512];
unsigned int size;
short int has_footer;
} id3Tag;
typedef struct id3v2Tag_s
{
// header
int tag_size;
short int unsync;
short int has_extheader;
short int is_experimental;
//extheader
int extheader_size;
int padding_size;
short int crc_data_present;
char crc_data[4];
// frames
DLL *frames;
} id3v2Tag;
typedef struct id3v2Frame_s
{
unsigned char id[4];
int datasize;
short int tagalter;
short int filealter;
short int readonly;
short int compression;
short int encryption;
short int grouping;
char *data;
} id3v2Frame;
#endif
extern int get_id3v2_tag(id3Tag *tag, char *filename);
extern int set_id3v2_tag(id3Tag *tag, char *filename);
extern int del_id3v2_tag(char *filename);
......@@ -109,7 +109,7 @@ then
echo "install: no input file specified"
exit 1
else
true
:
fi
if [ x"$dir_arg" != x ]; then
......@@ -120,7 +120,7 @@ if [ x"$dir_arg" != x ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
instcmd=$mkdirprog
fi
else
......@@ -128,9 +128,9 @@ else
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
if [ -f "$src" ] || [ -d "$src" ]
then
true
:
else
echo "install: $src does not exist"
exit 1
......@@ -141,7 +141,7 @@ else
echo "install: no destination specified"
exit 1
else
true
:
fi
# If destination is a directory, append the input filename; if your system
......@@ -151,7 +151,7 @@ else
then
dst="$dst"/`basename $src`
else
true
:
fi
fi
......@@ -163,8 +163,8 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
......@@ -183,7 +183,7 @@ while [ $# -ne 0 ] ; do
then
$mkdirprog "${pathcomp}"
else
true
:
fi
pathcomp="${pathcomp}/"
......@@ -194,10 +194,10 @@ if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
......@@ -216,7 +216,7 @@ else
then
dstfile=`basename $dst`
else
true
:
fi
# Make a temp file name in the proper directory.
......@@ -235,10 +235,10 @@ else
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
......
......@@ -20,6 +20,8 @@
#include "buffer2array.h"
#include "command.h"
#include "conf.h"
#include "list.h"
#include "myfprintf.h"
#include <unistd.h>
#include <stdio.h>
......@@ -27,23 +29,29 @@
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/param.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#define GREETING "MPD"
#define INTERFACE_MAX_BUFFER_LENGTH 1024
#define INTERFACE_MAX_BUFFER_LENGTH MAXPATHLEN+1024
#define INTERFACE_LIST_MODE_BEGIN "command_list_begin"
#define INTERFACE_LIST_MODE_END "command_list_end"
int interface_max_connections;
int interface_timeout;
typedef struct _Interface {
char buffer[INTERFACE_MAX_BUFFER_LENGTH+1];
char buffer[INTERFACE_MAX_BUFFER_LENGTH+2];
int bufferLength;
int fd; /* file descriptor */
FILE * fp; /* file pointer */
int open; /* open/used */
time_t lastTime;
List * commandList; /* for when in list mode */
List * bufferList; /* for output if client is slow */
} Interface;
Interface * interfaces = NULL;
......@@ -55,11 +63,14 @@ void openInterface(Interface * interface, int fd) {
interface->bufferLength = 0;
interface->fd = fd;
fcntl(interface->fd,F_SETFL,O_NONBLOCK);
interface->fp = fdopen(fd,"w");
interface->open = 1;
interface->lastTime = time(NULL);
interface->commandList = NULL;
interface->bufferList = NULL;
fprintf(interface->fp,"%s %s %s\n",COMMAND_RESPOND_OK,GREETING,VERSION);
myfprintf(interface->fp,"%s %s %s\n",COMMAND_RESPOND_OK,GREETING,VERSION);
}
void closeInterface(Interface * interface) {
......@@ -70,6 +81,9 @@ void closeInterface(Interface * interface) {
if(fclose(interface->fp)) {
fprintf(stderr,"Error closing file pointer\n");
}
if(interface->commandList) freeList(interface->commandList);
if(interface->bufferList) freeList(interface->bufferList);
}
void openAInterface(int fd) {
......@@ -79,7 +93,7 @@ void openAInterface(int fd) {
if(i==interface_max_connections) {
FILE * fp = fdopen(fd,"w");
fprintf(fp,"%s Max Connections Reached!\n",COMMAND_RESPOND_ERROR);
myfprintf(fp,"%s Max Connections Reached!\n",COMMAND_RESPOND_ERROR);
fclose(fp);
close(fd);
}
......@@ -89,35 +103,73 @@ void openAInterface(int fd) {
}
int interfaceReadInput(Interface * interface) {
if(read(interface->fd,interface->buffer+interface->bufferLength,1)) {
if(read(interface->fd,interface->buffer+interface->bufferLength,1)>0) {
int ret = 1;
interface->buffer[interface->bufferLength+1] = '\0';
if(interface->buffer[interface->bufferLength]!='\r') {
interface->bufferLength++;
}
if(interface->bufferLength>=INTERFACE_MAX_BUFFER_LENGTH) {
fprintf(stdout,"Buffer Overflow\n");
fprintf(stderr,"Buffer Overflow\n");
closeInterface(interface);
}
if(interface->buffer[interface->bufferLength-1]=='\n') {
int i;
char ** argArray;
int argArrayLength;
interface->buffer[interface->bufferLength-1] = '\0';
argArrayLength = buffer2array(interface->buffer,&argArray);
ret = processCommand(interface->fp,argArrayLength,argArray);
for(i=0;i<argArrayLength;i++) {
free(argArray[i]);
if(interface->commandList) {
if(strcmp(argArray[0],INTERFACE_LIST_MODE_END)==0) {
ListNode * node = interface->commandList->firstNode;
ret = 0;
while(node!=NULL) {
char ** argArray;
int argArrayLength;
argArrayLength = buffer2array((char *)node->data,&argArray);
ret = processCommand(interface->fp,argArrayLength,argArray);
freeArgArray(argArray,argArrayLength);
if(ret!=0) break;
node = node->nextNode;
}
if(ret==0) {
myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK);
}
else if(ret==COMMAND_RETURN_CLOSE) {
closeInterface(interface);
}
freeList(interface->commandList);
interface->commandList = NULL;
}
else {
insertInListWithoutKey(interface->commandList,strdup(interface->buffer));
}
}
free(argArray);
else {
if(strcmp(argArray[0],INTERFACE_LIST_MODE_BEGIN)==0) {
interface->commandList = makeList(free);
ret = 1;
}
else {
if(strcmp(argArray[0],INTERFACE_LIST_MODE_END)==0) {
myfprintf(interface->fp,"%s not in command list mode\n",COMMAND_RESPOND_ERROR);
ret = -1;
}
else ret = processCommand(interface->fp,argArrayLength,argArray);
if(ret==0) {
myfprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK);
}
else if(ret==COMMAND_RETURN_CLOSE) {
closeInterface(interface);
}
}
}
freeArgArray(argArray,argArrayLength);
interface->bufferLength = 0;
}
if(ret==0) {
fprintf(interface->fp,"%s\n",COMMAND_RESPOND_OK);
}
if(ret==COMMAND_RETURN_CLOSE) {
closeInterface(interface);
}
return ret;
}
else {
......@@ -133,7 +185,7 @@ void addInterfacesToFdSet(fd_set * fds) {
FD_ZERO(fds);
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open) {
if(interfaces[i].open && !interfaces[i].bufferList) {
FD_SET(interfaces[i].fd,fds);
}
}
......@@ -145,7 +197,7 @@ int readInputFromInterfaces() {
int i;
tv.tv_sec = 0;
tv.tv_usec = 0;
tv.tv_usec = 1000;
addInterfacesToFdSet(&fds);
......@@ -212,3 +264,79 @@ void closeOldInterfaces() {
}
}
}
void closeInterfaceWithFD(int fd) {
int i;
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].fd==fd) {
closeInterface(&(interfaces[i]));
}
}
}
void flushInterfaceBuffer(Interface * interface) {
ListNode * node = NULL;
char * str;
int ret;
while((node = interface->bufferList->firstNode)) {
str = (char *)node->data;
if((ret = write(interface->fd,str,strlen(str)))<0) break;
else if(ret<strlen(str)) {
str = strdup(&str[ret]);
free(node->data);
node->data = str;
}
else {
deleteNodeFromList(interface->bufferList,node);
}
}
if(!interface->bufferList->firstNode) {
freeList(interface->bufferList);
interface->bufferList = NULL;
}
else if(errno!=EAGAIN) closeInterface(interface);
}
void flushAllInterfaceBuffers() {
int i;
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].open && interfaces[i].bufferList) {
flushInterfaceBuffer(&interfaces[i]);
}
}
}
void interfacePrintWithFD(int fd,char * buffer) {
int i;
int ret;
if(!strlen(buffer)) return;
for(i=0;i<interface_max_connections;i++) {
if(interfaces[i].fd==fd) break;
}
if(i==interface_max_connections) return;
if(interfaces[i].bufferList) {
insertInListWithoutKey(interfaces[i].bufferList,(void *)strdup(buffer));
flushInterfaceBuffer(&interfaces[i]);
}
else {
if((ret = write(fd,buffer,strlen(buffer)))<0) {
if(errno==EAGAIN) {
interfaces[i].bufferList = makeList(free);
insertInListWithoutKey(interfaces[i].bufferList,(void *)strdup(buffer));
}
else closeInterface(&interfaces[i]);
}
else if(ret<strlen(buffer)) {
interfaces[i].bufferList = makeList(free);
insertInListWithoutKey(interfaces[i].bufferList,(void *)strdup(&buffer[ret]));
}
}
}
......@@ -27,6 +27,9 @@ void openAInterface(int fd);
void closeAllInterfaces();
void freeAllInterfaces();
void closeOldInterfaces();
void closeInterfaceWithFD(int fd);
void flushAllInterfaceBuffers();
void interfacePrintWithFD(int fd, char * buffer);
int readInputFromInterfaces();
......
libid3tag - ID3 tag manipulation library
Copyright (C) 2000-2003 Underbit Technologies, Inc.
$Id: CHANGES,v 1.2 2003/07/05 05:18:51 shank Exp $
===============================================================================
Version 0.15.0 (beta)
* Updated to autoconf 2.57, automake 1.7.5, libtool 1.4.3.
* Added new id3_tag_version(), id3_tag_options(), id3_tag_setlength(),
id3_frame_field(), id3_field_getlatin1(), id3_field_getfulllatin1(),
id3_genre_index(), id3_genre_number(), id3_latin1_ucs4duplicate(),
id3_utf16_ucs4duplicate(), and id3_utf8_ucs4duplicate() API routines.
* Properly exposed the id3_frame_new(), id3_frame_delete(), and
id3_field_type() API routines.
* Fixed a possible segmentation fault rendering ID3v1 tags when a tag
field exceeds the field length limit.
* Fixed a problem whereby the file interface could try to seek and read
data from a non-seekable stream, unrecoverably losing data from the
stream. (N.B. the fix does not work under Win32.)
* Fixed a problem reading ID3v2.2 frames which corrupted their frame IDs
and caused them not to be re-rendered.
* Improved rendering of the ID3v1 genre field from ID3v2 genre
names/numbers. The genre "Other" is used in place of non-translatable
genres.
* Rendering an empty ID3v1 tag now properly returns 0 length even when a
null buffer pointer is passed.
* Changed the file implementation to maintain information about present
but unparseable tags, instead of ignoring all tags and returning an
error.
* Added an external dependency on zlib (libz), which is no longer
included.
* Changed to build a shared library by default.
* Changed to use native Cygwin build by default; give --host=mingw32 to
`configure' to use MinGW (and avoid a dependency on the Cygwin DLL).
Version 0.14.2 (beta)
* Changed Cygwin builds to use MinGW; resulting Win32 executables no
longer have a dependency on Cygwin DLLs.
Version 0.14.1 (beta)
* Updated config.guess and config.sub to latest upstream versions.
* Enabled libtool versioning rather than release numbering.
* Renamed `libid3' to `libid3tag' and enabled installation as a separate
library.
* Several other small fixes.
Version 0.14.0 (beta)
* Added a new ID3 tag manipulation library (libid3). The required zlib
support is provided either by the host system or by the included static
library implementation (libz).
* Improved MSVC++ portability and added MSVC++ project files.
===============================================================================
libid3tag - ID3 tag manipulation library
Copyright (C) 2000-2003 Underbit Technologies, Inc.
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
If you would like to negotiate alternate licensing terms, you may do
so by contacting: Underbit Technologies, Inc. <info@underbit.com>
libid3tag - ID3 tag manipulation library
Copyright (C) 2000-2003 Underbit Technologies, Inc.
$Id: CREDITS,v 1.2 2003/07/05 05:18:51 shank Exp $
===============================================================================
AUTHOR
Except where otherwise noted, all code was authored by:
Robert Leslie <rob@underbit.com>
CONTRIBUTORS
Significant contributions have been incorporated with thanks to:
Mark Malson <mark@mmalson.com>
2002/10/09: frame.c
- Reported problem reading ID3v2.2 tag frames.
Brett Paterson <brett@fmod.org>
2001/10/28: global.h
- Reported missing <assert.h> et al. under MS Embedded Visual C.
===============================================================================
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.
##
## libid3tag - ID3 tag manipulation library
## Copyright (C) 2000-2003 Underbit Technologies, Inc.
##
## 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
##
## $Id: Makefile.am,v 1.3 2003/07/05 06:12:40 shank Exp $
##
## Process this file with automake to produce Makefile.in
SUBDIRS =
#DIST_SUBDIRS = msvc++
noinst_LTLIBRARIES = libid3tag.la
noinst_HEADERS = id3tag.h
## From the libtool documentation on library versioning:
##
## CURRENT
## The most recent interface number that this library implements.
##
## REVISION
## The implementation number of the CURRENT interface.
##
## AGE
## The difference between the newest and oldest interfaces that this
## library implements. In other words, the library implements all the
## interface numbers in the range from number `CURRENT - AGE' to
## `CURRENT'.
##
## If two libraries have identical CURRENT and AGE numbers, then the
## dynamic linker chooses the library with the greater REVISION number.
##
## 1. Start with version information of `0:0:0' for each libtool library.
##
## 2. Update the version information only immediately before a public
## release of your software. More frequent updates are unnecessary,
## and only guarantee that the current interface number gets larger
## faster.
##
## 3. If the library source code has changed at all since the last
## update, then increment REVISION (`C:R:A' becomes `C:r+1:A').
##
## 4. If any interfaces have been added, removed, or changed since the
## last update, increment CURRENT, and set REVISION to 0.
##
## 5. If any interfaces have been added since the last public release,
## then increment AGE.
##
## 6. If any interfaces have been removed since the last public release,
## then set AGE to 0.
version_current = 2
version_revision = 0
version_age = 2
version_info = $(version_current):$(version_revision):$(version_age)
EXTRA_DIST = genre.dat.sed \
CHANGES COPYRIGHT CREDITS README TODO VERSION
if DEBUG
debug = debug.c debug.h
else
debug =
endif
libid3tag_la_SOURCES = version.c ucs4.c latin1.c utf16.c utf8.c \
parse.c render.c field.c frametype.c compat.c \
genre.c frame.c crc.c util.c tag.c file.c \
version.h ucs4.h latin1.h utf16.h utf8.h \
parse.h render.h field.h frametype.h compat.h \
genre.h frame.h crc.h util.h tag.h file.h \
id3tag.h global.h genre.dat $(debug)
EXTRA_libid3tag_la_SOURCES = \
frametype.gperf compat.gperf genre.dat.in \
debug.c debug.h
libid3tag_la_LDFLAGS = -version-info $(version_info)
BUILT_SOURCES = frametype.c compat.c genre.dat
$(srcdir)/frametype.c: $(srcdir)/frametype.gperf Makefile.am
cd $(srcdir) && \
gperf -tCcTonD -K id -N id3_frametype_lookup -s -3 -k '*' \
frametype.gperf | \
sed -e 's/\(struct id3_frametype\);/\1/' | \
sed -e '/\$$''Id: /s/\$$//g' >frametype.c
$(srcdir)/compat.c: $(srcdir)/compat.gperf Makefile.am
cd $(srcdir) && \
gperf -tCcTonD -K id -N id3_compat_lookup -s -3 -k '*' \
compat.gperf | \
sed -e 's/\(struct id3_compat\);/\1/' | \
sed -e '/\$$''Id: /s/\$$//g' >compat.c
$(srcdir)/genre.dat: $(srcdir)/genre.dat.in $(srcdir)/genre.dat.sed Makefile.am
cd $(srcdir) && \
sed -n -f genre.dat.sed genre.dat.in | \
sed -e '/\$$''Id: /s/\$$//g' >genre.dat
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
again:
$(MAKE) clean
$(MAKE)
.PHONY: again
libid3tag - ID3 tag manipulation library
Copyright (C) 2000-2003 Underbit Technologies, Inc.
$Id: README,v 1.2 2003/07/05 05:18:51 shank Exp $
===============================================================================
INTRODUCTION
libid3tag is a library for reading and (eventually) writing ID3 tags, both
ID3v1 and the various versions of ID3v2.
See the file `id3tag.h' for the current library interface.
This package uses GNU libtool to arrange for zlib to be linked
automatically when you link your programs with this library. If you aren't
using GNU libtool, in some cases you may need to link with zlib
explicitly:
${link_command} ... -lid3tag -lz
===============================================================================
BUILDING AND INSTALLING
Note that this library depends on zlib 1.1.4 or later. If you don't have
zlib already, you can obtain it from:
http://www.gzip.org/zlib/
You must have zlib installed before you can build this package.
Windows Platforms
libid3tag can be built under Windows using either MSVC++ or Cygwin. A
MSVC++ project file can be found under the `msvc++' subdirectory.
To build libid3tag using Cygwin, you will first need to install the Cygwin
tools:
http://www.cygwin.com/
You may then proceed with the following POSIX instructions within the
Cygwin shell.
Note that by default Cygwin will build a library that depends on the
Cygwin DLL. You can use MinGW to build a library that does not depend on
the Cygwin DLL. To do so, give the option --host=mingw32 to `configure'.
Be certain you also link with a MinGW version of zlib.
POSIX Platforms (including Cygwin)
The code is distributed with a `configure' script that will generate for
you a `Makefile' and a `config.h' for your platform. See the file
`INSTALL' for generic instructions.
The specific options you may want to give `configure' are:
--disable-debugging do not compile with debugging support, and
use more optimizations
--disable-shared do not build a shared library
By default the package will build a shared library if possible for your
platform. If you want only a static library, use --disable-shared.
If zlib is installed in an unusual place or `configure' can't find it, you
may need to indicate where it is:
./configure ... CPPFLAGS="-I${include_dir}" LDFLAGS="-L${lib_dir}"
where ${include_dir} and ${lib_dir} are the locations of the installed
header and library files, respectively.
Experimenting and Developing
Further options for `configure' that may be useful to developers and
experimenters are:
--enable-debugging enable diagnostic debugging support and
debugging symbols
--enable-profiling generate `gprof' profiling code
===============================================================================
COPYRIGHT
Please read the `COPYRIGHT' file for copyright and warranty information.
Also, the file `COPYING' contains the full text of the GNU GPL.
Send inquiries, comments, bug reports, suggestions, patches, etc. to:
Underbit Technologies, Inc. <support@underbit.com>
See also the MAD home page on the Web:
http://www.underbit.com/products/mad/
===============================================================================
libid3tag - ID3 tag manipulation library
Copyright (C) 2000-2003 Underbit Technologies, Inc.
$Id: TODO,v 1.2 2003/07/05 05:18:51 shank Exp $
===============================================================================
libid3tag:
- finish file API
- fix API headers
0.15.0b
configure.ac:24
id3tag.h:334-337
msvc++/config.h:57
Makefile.am:63-65
This source diff could not be displayed because it is too large. You can view the blob instead.
%{
/*
* libid3tag - ID3 tag manipulation library
* Copyright (C) 2000-2003 Underbit Technologies, Inc.
*
* 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
*
* $Id: compat.gperf,v 1.2 2003/07/05 05:18:51 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <stdlib.h>
# include <string.h>
# ifdef HAVE_ASSERT_H
# include <assert.h>
# endif
# include "id3tag.h"
# include "compat.h"
# include "frame.h"
# include "field.h"
# include "parse.h"
# include "ucs4.h"
# define EQ(id) #id, 0
# define OBSOLETE 0, 0
# define TX(id) #id, translate_##id
static id3_compat_func_t translate_TCON;
%}
struct id3_compat;
%%
#
# ID3v2.2 and ID3v2.3 frames
#
# Only obsolete frames or frames with an equivalent ID3v2.4 frame ID are
# listed here. If a frame ID is not listed, it is assumed that the same
# frame ID is itself the equivalent ID3v2.4 frame ID.
#
# This list may also include frames with new content interpretations; the
# translation function will rewrite the contents to comply with ID3v2.4.
#
BUF, EQ(RBUF) /* Recommended buffer size */
CNT, EQ(PCNT) /* Play counter */
COM, EQ(COMM) /* Comments */
CRA, EQ(AENC) /* Audio encryption */
CRM, OBSOLETE /* Encrypted meta frame [obsolete] */
EQU, OBSOLETE /* Equalization [obsolete] */
EQUA, OBSOLETE /* Equalization [obsolete] */
ETC, EQ(ETCO) /* Event timing codes */
GEO, EQ(GEOB) /* General encapsulated object */
IPL, EQ(TIPL) /* Involved people list */
IPLS, EQ(TIPL) /* Involved people list */
LNK, EQ(LINK) /* Linked information */
MCI, EQ(MCDI) /* Music CD identifier */
MLL, EQ(MLLT) /* MPEG location lookup table */
PIC, EQ(APIC) /* Attached picture */
POP, EQ(POPM) /* Popularimeter */
REV, EQ(RVRB) /* Reverb */
RVA, OBSOLETE /* Relative volume adjustment [obsolete] */
RVAD, OBSOLETE /* Relative volume adjustment [obsolete] */
SLT, EQ(SYLT) /* Synchronised lyric/text */
STC, EQ(SYTC) /* Synchronised tempo codes */
TAL, EQ(TALB) /* Album/movie/show title */
TBP, EQ(TBPM) /* BPM (beats per minute) */
TCM, EQ(TCOM) /* Composer */
TCO, TX(TCON) /* Content type */
TCON, TX(TCON) /* Content type */
TCR, EQ(TCOP) /* Copyright message */
TDA, OBSOLETE /* Date [obsolete] */
TDAT, OBSOLETE /* Date [obsolete] */
TDY, EQ(TDLY) /* Playlist delay */
TEN, EQ(TENC) /* Encoded by */
TFT, EQ(TFLT) /* File type */
TIM, OBSOLETE /* Time [obsolete] */
TIME, OBSOLETE /* Time [obsolete] */
TKE, EQ(TKEY) /* Initial key */
TLA, EQ(TLAN) /* Language(s) */
TLE, EQ(TLEN) /* Length */
TMT, EQ(TMED) /* Media type */
TOA, EQ(TOPE) /* Original artist(s)/performer(s) */
TOF, EQ(TOFN) /* Original filename */
TOL, EQ(TOLY) /* Original lyricist(s)/text writer(s) */
TOR, EQ(TDOR) /* Original release year [obsolete] */
TORY, EQ(TDOR) /* Original release year [obsolete] */
TOT, EQ(TOAL) /* Original album/movie/show title */
TP1, EQ(TPE1) /* Lead performer(s)/soloist(s) */
TP2, EQ(TPE2) /* Band/orchestra/accompaniment */
TP3, EQ(TPE3) /* Conductor/performer refinement */
TP4, EQ(TPE4) /* Interpreted, remixed, or otherwise modified by */
TPA, EQ(TPOS) /* Part of a set */
TPB, EQ(TPUB) /* Publisher */
TRC, EQ(TSRC) /* ISRC (international standard recording code) */
TRD, OBSOLETE /* Recording dates [obsolete] */
TRDA, OBSOLETE /* Recording dates [obsolete] */
TRK, EQ(TRCK) /* Track number/position in set */
TSI, OBSOLETE /* Size [obsolete] */
TSIZ, OBSOLETE /* Size [obsolete] */
TSS, EQ(TSSE) /* Software/hardware and settings used for encoding */
TT1, EQ(TIT1) /* Content group description */
TT2, EQ(TIT2) /* Title/songname/content description */
TT3, EQ(TIT3) /* Subtitle/description refinement */
TXT, EQ(TEXT) /* Lyricist/text writer */
TXX, EQ(TXXX) /* User defined text information frame */
TYE, OBSOLETE /* Year [obsolete] */
TYER, OBSOLETE /* Year [obsolete] */
UFI, EQ(UFID) /* Unique file identifier */
ULT, EQ(USLT) /* Unsynchronised lyric/text transcription */
WAF, EQ(WOAF) /* Official audio file webpage */
WAR, EQ(WOAR) /* Official artist/performer webpage */
WAS, EQ(WOAS) /* Official audio source webpage */
WCM, EQ(WCOM) /* Commercial information */
WCP, EQ(WCOP) /* Copyright/legal information */
WPB, EQ(WPUB) /* Publishers official webpage */
WXX, EQ(WXXX) /* User defined URL link frame */
%%
static
int translate_TCON(struct id3_frame *frame, char const *oldid,
id3_byte_t const *data, id3_length_t length)
{
id3_byte_t const *end;
enum id3_field_textencoding encoding;
id3_ucs4_t *string = 0, *ptr, *endptr;
int result = 0;
/* translate old TCON syntax into multiple strings */
assert(frame->nfields == 2);
encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1;
end = data + length;
if (id3_field_parse(&frame->fields[0], &data, end - data, &encoding) == -1)
goto fail;
string = id3_parse_string(&data, end - data, encoding, 0);
if (string == 0)
goto fail;
ptr = string;
while (*ptr == '(') {
if (*++ptr == '(')
break;
endptr = ptr;
while (*endptr && *endptr != ')')
++endptr;
if (*endptr)
*endptr++ = 0;
if (id3_field_addstring(&frame->fields[1], ptr) == -1)
goto fail;
ptr = endptr;
}
if (*ptr && id3_field_addstring(&frame->fields[1], ptr) == -1)
goto fail;
if (0) {
fail:
result = -1;
}
if (string)
free(string);
return result;
}
/*
* NAME: compat->fixup()
* DESCRIPTION: finish compatibility translations
*/
int id3_compat_fixup(struct id3_tag *tag)
{
struct id3_frame *frame;
unsigned int index;
id3_ucs4_t timestamp[17] = { 0 };
int result = 0;
/* create a TDRC frame from obsolete TYER/TDAT/TIME frames */
/*
* TYE/TYER: YYYY
* TDA/TDAT: DDMM
* TIM/TIME: HHMM
*
* TDRC: yyyy-MM-ddTHH:mm
*/
index = 0;
while ((frame = id3_tag_findframe(tag, ID3_FRAME_OBSOLETE, index++))) {
char const *id;
id3_byte_t const *data, *end;
id3_length_t length;
enum id3_field_textencoding encoding;
id3_ucs4_t *string;
id = id3_field_getframeid(&frame->fields[0]);
assert(id);
if (strcmp(id, "TYER") != 0 && strcmp(id, "YTYE") != 0 &&
strcmp(id, "TDAT") != 0 && strcmp(id, "YTDA") != 0 &&
strcmp(id, "TIME") != 0 && strcmp(id, "YTIM") != 0)
continue;
data = id3_field_getbinarydata(&frame->fields[1], &length);
assert(data);
if (length < 1)
continue;
end = data + length;
encoding = id3_parse_uint(&data, 1);
string = id3_parse_string(&data, end - data, encoding, 0);
if (id3_ucs4_length(string) < 4) {
free(string);
continue;
}
if (strcmp(id, "TYER") == 0 ||
strcmp(id, "YTYE") == 0) {
timestamp[0] = string[0];
timestamp[1] = string[1];
timestamp[2] = string[2];
timestamp[3] = string[3];
}
else if (strcmp(id, "TDAT") == 0 ||
strcmp(id, "YTDA") == 0) {
timestamp[4] = '-';
timestamp[5] = string[2];
timestamp[6] = string[3];
timestamp[7] = '-';
timestamp[8] = string[0];
timestamp[9] = string[1];
}
else { /* TIME or YTIM */
timestamp[10] = 'T';
timestamp[11] = string[0];
timestamp[12] = string[1];
timestamp[13] = ':';
timestamp[14] = string[2];
timestamp[15] = string[3];
}
free(string);
}
if (timestamp[0]) {
id3_ucs4_t *strings;
frame = id3_frame_new("TDRC");
if (frame == 0)
goto fail;
strings = timestamp;
if (id3_field_settextencoding(&frame->fields[0],
ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1 ||
id3_field_setstrings(&frame->fields[1], 1, &strings) == -1 ||
id3_tag_attachframe(tag, frame) == -1) {
id3_frame_delete(frame);
goto fail;
}
}
if (0) {
fail:
result = -1;
}
return result;
}
/*
* libid3tag - ID3 tag manipulation library
* Copyright (C) 2000-2003 Underbit Technologies, Inc.
*
* 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
*
* $Id: compat.h,v 1.2 2003/07/05 05:18:51 shank Exp $
*/
# ifndef LIBID3TAG_COMPAT_H
# define LIBID3TAG_COMPAT_H
# include "id3tag.h"
typedef int id3_compat_func_t(struct id3_frame *, char const *,
id3_byte_t const *, id3_length_t);
struct id3_compat {
char const *id;
char const *equiv;
id3_compat_func_t *translate;
};
struct id3_compat const *id3_compat_lookup(register char const *,
register unsigned int);
int id3_compat_fixup(struct id3_tag *);
# endif
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to enable diagnostic debugging support. */
#undef DEBUG
/* Define to 1 if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `ftruncate' function. */
#undef HAVE_FTRUNCATE
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to disable debugging assertions. */
#undef NDEBUG
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
#undef inline
This source diff could not be displayed because it is too large. You can view the blob instead.
dnl -*- m4 -*-
dnl
dnl libid3tag - ID3 tag manipulation library
dnl Copyright (C) 2000-2003 Underbit Technologies, Inc.
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dnl
AC_REVISION([$Id: configure.ac,v 1.3 2003/07/05 05:39:48 shank Exp $])dnl
dnl Process this file with autoconf to produce a configure script.
AC_INIT([ID3 Tag], [0.15.0b], [support@underbit.com], [libid3tag])
AC_PREREQ(2.53)
AC_CONFIG_SRCDIR([id3tag.h])
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER([config.h])
dnl System type.
AC_CANONICAL_HOST
dnl Checks for programs.
AC_PROG_CC
if test "$GCC" = yes
then
case "$host" in
*-*-mingw*)
case "$build" in
*-*-cygwin*)
CPPFLAGS="$CPPFLAGS -mno-cygwin"
LDFLAGS="$LDFLAGS -mno-cygwin"
;;
esac
esac
dnl case "$host" in
dnl *-*-cygwin* | *-*-mingw*)
dnl LDFLAGS="$LDFLAGS -no-undefined -mdll"
dnl ;;
dnl esac
fi
dnl Support for libtool.
AC_DISABLE_SHARED
dnl AC_LIBTOOL_WIN32_DLL
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
dnl Compiler options.
arch=""
debug=""
optimize=""
profile=""
set -- $CFLAGS
CFLAGS=""
if test "$GCC" = yes
then
CFLAGS="-Wall"
fi
while test $# -gt 0
do
case "$1" in
-Wall)
if test "$GCC" = yes
then
:
else
CFLAGS="$CFLAGS $1"
fi
shift
;;
-g)
debug="-g"
shift
;;
-mno-cygwin)
shift
;;
-m*)
arch="$arch $1"
shift
;;
-fomit-frame-pointer)
shift
;;
-O*|-f*)
optimize="$1"
shift
;;
*)
CFLAGS="$CFLAGS $1"
shift
;;
esac
done
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(assert.h unistd.h)
AC_CHECK_HEADER(zlib.h, [], [
AC_MSG_ERROR([zlib.h was not found
*** You must first install zlib (libz) before you can build this package.
*** If zlib is already installed, you may need to use the CPPFLAGS
*** environment variable to specify its installed location, e.g. -I<dir>.])
])
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
dnl Checks for library functions.
AC_CHECK_FUNCS(ftruncate)
AC_CHECK_LIB(z, compress2, [], [
AC_MSG_ERROR([libz was not found
*** You must first install zlib (libz) before you can build this package.
*** If zlib is already installed, you may need to use the LDFLAGS
*** environment variable to specify its installed location, e.g. -L<dir>.])
])
dnl handle --enable and --disable options
AC_CACHE_SAVE
AC_MSG_CHECKING([whether to enable profiling])
AC_ARG_ENABLE(profiling, AC_HELP_STRING([--enable-profiling],
[generate profiling code]),
[
case "$enableval" in
yes) profile="-pg" ;;
esac
])
AC_MSG_RESULT(${enable_profiling-no})
AC_MSG_CHECKING([whether to enable debugging])
AC_ARG_ENABLE(debugging, AC_HELP_STRING([--enable-debugging],
[enable diagnostic debugging support])
AC_HELP_STRING([--disable-debugging],
[do not enable debugging and use more optimization]),
[
case "$enableval" in
yes)
AC_DEFINE(DEBUG, 1,
[Define to enable diagnostic debugging support.])
optimize=""
;;
no)
if test -n "$profile"
then
AC_MSG_ERROR(--enable-profiling and --disable-debugging are incompatible)
fi
AC_DEFINE(NDEBUG, 1,
[Define to disable debugging assertions.])
debug=""
if test "$GCC" = yes
then
optimize="$optimize -fomit-frame-pointer"
fi
;;
esac
])
AC_MSG_RESULT(${enable_debugging-default})
AM_CONDITIONAL(DEBUG, test ${enable_debugging-default} = yes)
dnl Create output files.
test -n "$arch" && CFLAGS="$CFLAGS $arch"
test -n "$debug" && CFLAGS="$CFLAGS $debug"
test -n "$optimize" && CFLAGS="$CFLAGS $optimize"
test -n "$profile" && CFLAGS="$CFLAGS $profile" LDFLAGS="$LDFLAGS $profile"
dnl LTLIBOBJS=`echo "$LIBOBJS" | sed -e 's/\.o/.lo/g'`
dnl AC_SUBST(LTLIBOBJS)
AC_CONFIG_FILES([Makefile \
libid3tag.list])
AC_OUTPUT
/*
* libid3tag - ID3 tag manipulation library
* Copyright (C) 2000-2003 Underbit Technologies, Inc.
*
* 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
*
* $Id: crc.c,v 1.2 2003/07/05 05:18:51 shank Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include "id3tag.h"
# include "crc.h"
static
unsigned long const crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
/*
* NAME: crc->calculate()
* DESCRIPTION: compute CRC-32 value (ISO 3309)
*/
unsigned long id3_crc_calculate(id3_byte_t const *data, id3_length_t length)
{
register unsigned long crc;
for (crc = 0xffffffffL; length >= 8; length -= 8) {
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
}
switch (length) {
case 7: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
case 6: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
case 5: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
case 4: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
case 3: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
case 2: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
case 1: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
case 0: break;
}
return crc ^ 0xffffffffL;
}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment