Commit d44d5753 authored by Led's avatar Led

0.6.0

parent 1e912f80
......@@ -37,10 +37,6 @@ find <string type> <string what>
_type_ should be "album", "artist", or "title"
_what_ is what to find
info <string file>
fetches id3 tag of _file_
NOTE: do not use this, meant for debugging only
kill
kill mpd
......
ver 0.6.0 (2003/5/25)
1) Add ogg vorbis support
2) Fix two bugs relating to tables, one for search by title, and one where we
freed the tables before directories, causing a segfault
ver 0.5.0-0.5.2
Initial release(s). Support for MP3 via mpg123
Music Player Daemon - FAQ
By: Nick Texidor
Q) How do I install mpd.
A) The usual way :^). untar the archive file, run 'make' (or 'make ogg' for
ogg vorbis support). Then, as su, 'make install'.
Q) How do I run mpd.
A) Change to the path mpd was installed to, i.e. /usr/local/mpd. Type
'mpd <port> <mp3/ogg directory> <playlist directory> <log file> <error file>'
i.e. mpd 2100 /mnt/jukebox /usr/local/mpd/playlists /usr/local/mpd/mpd.log /usr/local/mpd/mpd.error
Once mpd starts, it will explore your MP3/Ogg directory.
Q) How do I tell mpd to play music?
A) You can use a telnet interface (telnet <machine-name> <port>), or you
can download phpMp and queue songs via a web interface.
Q) How do I use telnet to play music using mpd?
A) login to the telnet session (telnet <machine-name> <port>). You
should see 'OK MPD 0.x.x' (where x is a number).
To queue songs to play, you use the command ADD, i.e.:
add "/path/to/song/song.mp3"
This should respond with 'OK'. If it says that it's an invalid mp3
file, then check the path. The path is relative to your current path.
To check the playlist, type PLAYLIST and press enter. To start
the playlist, type PLAY n (where n is a number from the
playlist, 0 would start playing from the top of the playlist).
Other commands include:
clear - to clear the playlist
pause - to pause playback
lsinfo <directory [optional]> - list contents of directory
save <file name> - saves the current playlist
shuffle - shuffles the playlist
find album|artist|title <search string> - Searches the specified field for
requested string
stop - Stop playing
update - Updates the MP3/Ogg Directory
Q) How do I start mpd automatically at boot time
A) Currently, there isn't a "nice" way of doing this. You can start it
as root (beware!) by entering 'mpd 2100 /mnt/jukebox /usr/local/mpd/playlists/usr/local/mpd/mpd.log /usr/local/mpd/mpd.error'
into your /etc/rc.d/rc.local file.
Q) What do I need to use mpd?
A) 1) mpg123 (or preferably mpg321)
and/or
2) ogg, vorbis, and libao (make sure you have the libogg, libvorbis, and libao
development and library packages installed for your distro. For Red Hat, the
rpm's are libogg, libogg-devel, libvorbis, libvorbis-devel, libao, and i
libao-devel)
Q) I queued a song to the playlist, but when mpd played it, it
didn't play properly
A) hmm, we haven't gotten to the bottom of this yet! It seems some
headers cause some mp3's to not play properly, and instead, appears to
play the track at very highspeed resulting in squeaking. This appears
to be a problem with mpg123. mpg321 has better results, but the track
seems to be distorted, while xmms plays the track without any problems.
Q) How can I get mpd to start playing music automatically when it starts
up
A) This can be done with a bit of jiggery pokery using the rc.local
script. After the command to start mpd, you can automate a telnet
session to load a playlist and issue a shuffle command. (Alternately,
hassle Warren to implement such a wonder feature) :^)
(From Warren - something is coming sonn)
Q) Can I send the output from mpd to IceCast/ShoutCast
A) No. Again, if you email your favourite mpd author, he may be able to
implement this little beaut of a feature! :^)
(if you have a gazillion US dollars to donate to warren's legal defense,
this feature can be implemented more quickly).
......@@ -6,6 +6,26 @@ Requirements
mpg123 - http://www.mpg123.de (MPD has been tested with 0.59q and 0.59r)
(mpg123 is included with many distributions and supports many platforms)
or
mpg321 - http://mpg321.sourceforge.net
(debian and other distributions substitute mpg123 with mpg321, if so, make
sure mpg123 is symlinked to mpg321)
Optional
--------
Ogg Vorbis - http://www.xiph.org/ogg/vorbis/
(This comes with most/all distrobutions. Make sure you have both the
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).
libao - http://www.xiph.org/ogg/vorbis/ (You need this for ogg vorbis)
(This also comes with most/all distrobutions. Make sure you have both
the libao libs and development packages for your distrobution installed.
For Red Hat 8.0, the neccessary packages are: libao and libao-devel)
Download
--------
......@@ -26,6 +46,14 @@ $ cd mpd-x.x.x
$ make
NOTE: for Ogg Vorbis support run make with the "ogg" target:
$ make ogg
NOTE: to recompile you must remove the compiled files with:
$ make clean
Install
-------
......
EXEC = mpd
OGG_MAKEFILE = Makefile.ogg
-include Makefile.ogg
PREFIX = /usr/local
BIN_DIR = $(PREFIX)/bin
INSTALL_DIR = $(PREFIX)/$(EXEC)
CC = gcc
CFLAGS = -Wall
LIBS = $(OGG_LIBS) -ldl
INCLUDES =
CFLAGS = -Wall $(INCLUDES) $(HAVE_OGG)
OFLAGS = -Wall
DFLAGS = -MM
DFLAGS = -MM $(INCLUDES) $(HAVE_OGG)
SOURCES = main.c buffer2array.c mpg123.c interface.c command.c playlist.c ls.c \
info.c id3v2lib/charset.c id3v2lib/lib_id3v2.3.c id3v1lib/lib_id3v1.c \
id3v2lib/charset.c id3v2lib/lib_id3v2.3.c id3v1lib/lib_id3v1.c \
id3v2lib/lib_id3v2.2.c song.c list.c directory.c tables.c utils.c \
tag.c
tag.c player.c ogg.c listen.c
OBJECTS = $(SOURCES:.c=.o)
DEPENDFILE =Makefile.depend
DEPENDFILE = Makefile.depend
all: $(EXEC)
ogg: ogg-make
$(MAKE) all
$(MAKE) clean-ogg-make
ogg-make:
echo "HAVE_OGG = -DHAVE_OGG" > $(OGG_MAKEFILE)
echo "OGG_LIBS = -lvorbisfile -lvorbis -lao" >> $(OGG_MAKEFILE)
$(EXEC): $(OBJECTS)
$(CC) $(OFLAGS) -o $(EXEC) $(OBJECTS)
$(CC) $(OFLAGS) -o $(EXEC) $(OBJECTS) $(LIBS)
deps:
$(CC) $(DFLAGS) $(SOURCES) > $(DEPENDFILE)
-include $(DEPENDFILE)
install: $(EXEC)
mkdir -p $(INSTALL_DIR)
cp $(EXEC) $(INSTALL_DIR)
ln -s $(INSTALL_DIR)/$(EXEC) $(BIN_DIR)/$(EXEC)
uninstall:
rm $(BIN_DIR)/$(EXEC)
rm $(INSTALL_DIR)/$(EXEC)
rm -r $(INSTALL_DIR)
clean:
rm -f $(EXEC) $(OBJECTS)
cleandeps:
clean-deps:
rm -f $(DEPENDFILE)
cleanall: clean cleandeps
clean-ogg-make:
rm -f $(OGG_MAKEFILE)
clean-all: clean clean-deps clean-ogg-make
......@@ -2,10 +2,10 @@
Music Player Daemon (MPD)
http://musicpd.sourceforge.net
A daemon for playing music (currently mp3's). Music is played through the
server's audio device. The daemon stores info about all availabe music, and
this info can be easily searched and retrieved. Player control, info retrieval,
and playlist management can all be managed remotely.
A daemon for playing music (currently mp3 and ogg vorbis). Music is played
through the server's audio device. The daemon stores info about all availabe
music, and this info can be easily searched and retrieved. Player control, info
retrieval, and playlist management can all be managed remotely.
To install MPD, see INSTALL.
......
1) Search by Filename
2) buffer support for OGG
3) use autoconf and automake
4) broadcast messages (including status changes/updates)
5) store song times (possibly after playing)
6) add a set a flags (such as BAD MP3)
Music Player Daemon (MPD) - UPGRADING
Upgrading from 0.5.x to 0.6.0
-----------------------------
If you have not compiled MPD with "make ogg", then nothing is needed.
If you compiled with "make ogg", just use "update" (availabe via the phpMp
interface) to add your ogg's to MPD's list of available music.
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -19,10 +17,9 @@
*/
#include "command.h"
#include "mpg123.h"
#include "player.h"
#include "playlist.h"
#include "ls.h"
#include "info.h"
#include "directory.h"
#include "tables.h"
......@@ -46,7 +43,6 @@
#define COMMAND_LS "ls"
#define COMMAND_LSINFO "lsinfo"
#define COMMAND_RM "rm"
#define COMMAND_INFO "info"
#define COMMAND_PLAYLISTINFO "playlistinfo"
#define COMMAND_FIND "find"
#define COMMAND_SEARCH "search"
......@@ -61,20 +57,20 @@ int commandStatus(FILE * fp,int argArrayLength, char ** argArray) {
return -1;
}
switch(mpg123_state) {
case MPG123_STATE_STOP:
switch(getPlayerState()) {
case PLAYER_STATE_STOP:
state = strdup(COMMAND_STOP);
break;
case MPG123_STATE_PAUSE:
case PLAYER_STATE_PAUSE:
state = strdup(COMMAND_PAUSE);
break;
case MPG123_STATE_PLAY:
case PLAYER_STATE_PLAY:
state = strdup(COMMAND_PLAY);
break;
}
if(mpg123_state>0) {
fprintf(fp,"%s %i %i:%i\n",state,playlist.current,mpg123_elapsedTime,mpg123_totalTime);
if(getPlayerState()>0) {
fprintf(fp,"%s %i %i:%i\n",state,playlist.current,getPlayerElapsedTime(),getPlayerTotalTime());
}
else {
fprintf(fp,"%s\n",state);
......@@ -109,14 +105,14 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) {
fprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]);
return -1;
}
return mpg123stop(fp);
return playerStop(fp);
}
else if(0==strcmp(argArray[0],COMMAND_PAUSE)) {
if(argArrayLength!=1) {
fprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]);
return -1;
}
return mpg123pause(fp);
return playerPause(fp);
}
else if(0==strcmp(argArray[0],COMMAND_STATUS)) {
return commandStatus(fp,argArrayLength,argArray);
......@@ -134,13 +130,6 @@ int processCommand(FILE * fp, int argArrayLength, char ** argArray) {
}
return addToPlaylist(fp,argArray[1]);
}
else if(0==strcmp(argArray[0],COMMAND_INFO)) {
if(argArrayLength!=2) {
fprintf(fp,"%s wrong number of arguments for \"%s\"\n",COMMAND_RESPOND_ERROR,argArray[0]);
return -1;
}
return info(fp,argArray[1]);
}
else if(0==strcmp(argArray[0],COMMAND_SAVE)) {
char * file;
int ret;
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -105,7 +103,7 @@ int updateInDirectory(Directory * directory, char * shortname, char * name) {
Song * song;
Directory * subDir;
if((mtime = isMp3(name))) {
if((mtime = isMusic(name))) {
if(0==findInList(directory->songs,shortname,(void **)&song)) {
printf("adding %s\n",name);
addToDirectory(directory,shortname,name);
......@@ -179,7 +177,7 @@ int removeDeletedFromDirectory(Directory * directory) {
node = directory->songs->firstNode;
while(node) {
if(findInList(entList,node->key,(void **)&name)) {
if(!isMp3(name)) {
if(!isMusic(name)) {
removeSongFromDirectory(directory,node->key,name);
}
}
......@@ -273,7 +271,7 @@ int addToDirectory(Directory * directory, char * shortname, char * name) {
if(isDir(name)) {
return addSubDirectoryToDirectory(directory,shortname,name);
}
else if(isMp3(name)) {
else if(isMusic(name)) {
Song * song;
song = addSongToList(directory->songs,shortname,name);
if(!song) return -1;
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
/* 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 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 "info.h"
#include "command.h"
#include "tag.h"
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
int info(FILE * fp, char * file) {
MpdTag * tag;
struct stat st;
if(stat(file,&st)) {
fprintf(fp,"%s not able to stat file\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(!S_ISREG(st.st_mode)) {
fprintf(fp,"%s not a file\n",COMMAND_RESPOND_ERROR);
return -1;
}
if((tag=id3Dup(file))) {
printMpdTag(fp,tag);
freeMpdTag(tag);
return 0;
}
fprintf(fp,"%s problems geting id3 info\n",COMMAND_RESPOND_ERROR);
return -1;
}
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -30,7 +28,7 @@
#include <sys/types.h>
#include <string.h>
#define VERSION "0.5.2"
#define VERSION "0.6.0"
#define GREETING "MPD"
#define INTERFACE_MAX_BUFFER_LENGTH 1024
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
/* the Music Player Daemon (MPD)
* (c)2002 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 "listen.h"
#include "interface.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#define MAXHOSTNAME 1024
int listenSocket;
int establish(unsigned short port) {
char myname[MAXHOSTNAME+1];
int sock;
struct sockaddr_in sockAddr;
struct hostent * he;
memset(&sockAddr, 0, sizeof(struct sockaddr_in));
gethostname(myname,MAXHOSTNAME);
he = gethostbyname(myname);
if(he == NULL) {
fprintf(stderr,"he == NULL\n");
return -1;
}
sockAddr.sin_family = he->h_addrtype;
sockAddr.sin_port = htons(port);
if((sock = socket(AF_INET,SOCK_STREAM,0)) < 0) {
fprintf(stderr,"socket < 0\n");
return -1;
}
if(bind(sock,(struct sockaddr *)&sockAddr,sizeof(struct sockaddr_in)) < 0) {
fprintf(stderr,"bind < 0\n");
close(sock);
return -1;
}
listen(sock,0);
return sock;
}
void getConnections(int sock) {
fd_set fdsr;
int fd;
struct timeval tv;
tv.tv_sec = tv.tv_usec = 0;
fflush(NULL);
FD_ZERO(&fdsr);
FD_SET(sock,&fdsr);
if(select(sock+1,&fdsr,NULL,NULL,&tv)==1 &&
((fd = accept(sock,NULL,NULL)) >= 0)) {
openAInterface(fd);
}
else if(fd<0) {
fprintf(stderr,"Problems accept()'ing\n");
}
}
/* the Music Player Daemon (MPD)
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -18,11 +16,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef INFO_H
#define INFO_H
#ifndef LISTEN_H
#define LISTEN_H
extern int listenSocket;
#include <stdio.h>
int establish(unsigned short port);
int info(FILE * fp, char * file);
void getConnections(int sock);
#endif
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -53,7 +51,7 @@ int ls(FILE * fp, char * dirname) {
if(stat(s,&st)==0) {
c = 0;
if(S_ISDIR(st.st_mode)) c = 'd';
else if(isMp3(s)) c = 'm';
else if(isMusic(s)) c = 'm';
if(c && dirname==cwd) {
fprintf(fp,"%c \"%s\"\n",c,ent->d_name);
}
......@@ -104,6 +102,42 @@ int lsPlaylists(FILE * fp) {
return 0;
}
time_t isMusic(char * file) {
time_t ret;
#ifdef HAVE_OGG
if((ret = isOgg(file))>0) return ret;
else
#endif
ret = isMp3(file);
return ret;
}
time_t isOgg(char * file) {
struct stat st;
if(stat(file,&st)==0) {
if(S_ISREG(st.st_mode)) {
char * dup;
char * cLast;
char * cNext;
int ret = 0;
dup = strdup(file);
cNext = cLast = strtok(dup,".");
while((cNext = strtok(NULL,"."))) cLast = cNext;
if(cLast && 0==strcasecmp(cLast,"ogg")) {
ret = st.st_mtime;
}
free(dup);
return ret;
}
else return 0;
}
return 0;
}
time_t isMp3(char * file) {
struct stat st;
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -24,14 +22,16 @@
#include <stdio.h>
#include <time.h>
#include "id3v2lib/lib_id3v2.3.h"
int ls(FILE * fp, char * dir);
int lsPlaylists(FILE * fp);
time_t isMp3(char * file);
time_t isOgg(char * file);
time_t isMusic(char * file);
time_t isDir(char * name);
#endif
......@@ -2,8 +2,6 @@
* (c)2002 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -20,88 +18,27 @@
#include "interface.h"
#include "command.h"
#include "mpg123.h"
#include "playlist.h"
#include "directory.h"
#include "tables.h"
#include "player.h"
#include "listen.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#define MAXHOSTNAME 1024
void usage(char * argv[]) {
fprintf(stderr,"usage: %s <port> <mp3 dir> <playlist dir> <log file> <error file>\n",argv[0]);
}
int establish(unsigned short port) {
char myname[MAXHOSTNAME+1];
int sock;
struct sockaddr_in sockAddr;
struct hostent * he;
memset(&sockAddr, 0, sizeof(struct sockaddr_in));
gethostname(myname,MAXHOSTNAME);
he = gethostbyname(myname);
if(he == NULL) {
fprintf(stderr,"he == NULL\n");
return -1;
}
sockAddr.sin_family = he->h_addrtype;
sockAddr.sin_port = htons(port);
if((sock = socket(AF_INET,SOCK_STREAM,0)) < 0) {
fprintf(stderr,"socket < 0\n");
return -1;
}
if(bind(sock,(struct sockaddr *)&sockAddr,sizeof(struct sockaddr_in)) < 0) {
fprintf(stderr,"bind < 0\n");
close(sock);
return -1;
}
listen(sock,0);
return sock;
}
void getConnections(int sock) {
fd_set fdsr;
int fd;
struct timeval tv;
tv.tv_sec = tv.tv_usec = 0;
fflush(NULL);
FD_ZERO(&fdsr);
FD_SET(sock,&fdsr);
if(select(sock+1,&fdsr,NULL,NULL,&tv)==1 &&
((fd = accept(sock,NULL,NULL)) >= 0)) {
openAInterface(fd);
}
else if(fd<0) {
fprintf(stderr,"Problems accept()'ing\n");
}
fprintf(stderr,"usage: %s <port> <mp3/ogg dir> <playlist dir> <log file> <error file>\n",argv[0]);
}
int main(int argc, char * argv[]) {
int port;
int sock;
struct stat st;
FILE * out;
FILE * err;
......@@ -168,7 +105,7 @@ int main(int argc, char * argv[]) {
}
}
if((sock = establish(port))<0) {
if((listenSocket = establish(port))<0) {
fprintf(stderr,"error bindping port\n");
return -1;
}
......@@ -182,21 +119,21 @@ int main(int argc, char * argv[]) {
dup2(fileno(err),STDERR_FILENO);
while(COMMAND_RETURN_KILL!=readInputFromInterfaces()) {
mpg123processMessages();
getConnections(sock);
playerProcessMessages();
getConnections(listenSocket);
closeOldInterfaces();
usleep(1000);
}
clearPlaylist(stderr);
closeAllInterfaces();
close(sock);
close(listenSocket);
mpg123stop(stderr);
mpg123kill();
playerStop(stderr);
playerKill();
closeTables();
closeMp3Directory();
closeTables();
return 0;
}
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -22,7 +20,9 @@
#include "command.h"
#include "interface.h"
#include "playlist.h"
#include "player.h"
#include "ls.h"
#include "listen.h"
#include <stdio.h>
#include <unistd.h>
......@@ -47,11 +47,10 @@ int mpg123_bufferLength = 0;
int mpg123_totalTime = 0;
int mpg123_elapsedTime = 0;
int mpg123_reportedElapsedTime = 0;
int mpg123_state = MPG123_STATE_STOP;
int mpg123_state = PLAYER_STATE_STOP;
int mpg123_leavePlay = 0;
int mpg123_leavePause = 0;
int mpg123_error = 0;
int mpg123_stopAtEnd = 0;
int mpg123_lastFrame = 0;
void mpg123_sigHandler(int signal) {
......@@ -61,12 +60,13 @@ void mpg123_sigHandler(int signal) {
close(mpg123_recv);
close(mpg123_send);
close(mpg123_stderr);
if(mpg123_state==MPG123_STATE_PLAY) {
if(mpg123_state==PLAYER_STATE_PLAY) {
mpg123_state = PLAYER_STATE_STOP;
mpg123_leavePlay = 1;
fprintf(stderr,"mpg123 died while playing\n");
nextSongInPlaylist(stderr);
}
mpg123_state = MPG123_STATE_STOP;
else mpg123_state = PLAYER_STATE_STOP;
}
}
......@@ -74,7 +74,6 @@ int mpg123init() {
int fd_send[2], fd_recv[2], fd_stderr[2];
mpg123_error = 0;
mpg123_stopAtEnd = 0;
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_send)<0) {
fprintf(stderr,"%s Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
......@@ -95,6 +94,7 @@ int mpg123init() {
mpg123_pid = fork();
if(mpg123_pid==0) {
close(listenSocket);
closeAllInterfaces();
close(fd_send[0]);
close(fd_recv[0]);
......@@ -137,8 +137,6 @@ int mpg123init() {
int mpg123play(FILE * fp, char * file) {
char string[1024];
mpg123_leavePlay = 0;
if(fp==NULL) fp=stderr;
if(!isMp3(file)) {
......@@ -146,18 +144,27 @@ int mpg123play(FILE * fp, char * file) {
return -1;
}
if(!mpg123_pid) {
if(mpg123init()<0) return -1;
if(mpg123stop(fp)<0) return -1;
if(mpg123init()<0) {
fprintf(fp,"%s problems init'ing mpg123\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(mpg123_pid<=0) {
printf("OOOPS, mpg123_pid = %i\n",mpg123_pid);
}
mpg123_leavePlay = 0;
mpg123_state = PLAYER_STATE_PLAY;
sprintf(string,"LOAD %s\n",file);
if(write(mpg123_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
mpg123_state = MPG123_STATE_PLAY;
/*sleep until status is updated*/
while(!mpg123_leavePlay) {
mpg123processMessages();
......@@ -176,23 +183,23 @@ int mpg123play(FILE * fp, char * file) {
int mpg123stop(FILE * fp) {
if(mpg123_pid>0) {
char string[1024];
if(mpg123_state==MPG123_STATE_PAUSE) {
if(mpg123_state==PLAYER_STATE_PAUSE) {
if(mpg123pause(fp)<0) return -1;
}
mpg123_state = MPG123_STATE_STOP;
mpg123_state = PLAYER_STATE_STOP;
sprintf(string,"QUIT\n");
if(write(mpg123_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
wait3(NULL,WUNTRACED,NULL);
waitpid(mpg123_pid,NULL,WUNTRACED);
if(mpg123_pid>0) {
fprintf(fp,"oh shit\n");
mpg123kill();
}
}
mpg123_state = MPG123_STATE_STOP;
mpg123_state = PLAYER_STATE_STOP;
return 0;
}
......@@ -212,11 +219,11 @@ int mpg123pause(FILE * fp) {
usleep(1000);
}
if(mpg123_state==MPG123_STATE_PLAY) {
mpg123_state = MPG123_STATE_PAUSE;
if(mpg123_state==PLAYER_STATE_PLAY) {
mpg123_state = PLAYER_STATE_PAUSE;
}
else if(mpg123_state==MPG123_STATE_PAUSE) {
mpg123_state = MPG123_STATE_PLAY;
else if(mpg123_state==PLAYER_STATE_PAUSE) {
mpg123_state = PLAYER_STATE_PLAY;
}
}
......@@ -235,7 +242,7 @@ int mpg123readline() {
rc = read(mpg123_recv,mpg123_buffer+mpg123_bufferLength,1);
if(rc<=0) {
/*mpg123_pid = 0;
mpg123_state = MPG123_STATE_STOP;*/
mpg123_state = PLAYER_STATE_STOP;*/
return -1;
}
if(mpg123_buffer[mpg123_bufferLength]=='\0' || mpg123_buffer[mpg123_bufferLength]=='\n' || mpg123_bufferLength == MAX_BUFFER_LENGTH) {
......@@ -269,10 +276,10 @@ int mpg123gotErrors() {
if(errorBuffer[errorBufferLength]=='\0' || errorBuffer[errorBufferLength]=='\n' || errorBufferLength == MAX_BUFFER_LENGTH) {
errorBuffer[errorBufferLength] = '\0';
errorBufferLength = 0;
fprintf(stderr,"%s %s\n",COMMAND_RESPOND_ERROR,errorBuffer);
if(!strncmp("Junk",errorBuffer,strlen("Junk"))) {
return 0;
}
fprintf(stderr,"%s %s\n",COMMAND_RESPOND_ERROR,errorBuffer);
mpg123kill();
return 1;
}
......@@ -298,25 +305,18 @@ int mpg123processMessages() {
mpg123_reportedElapsedTime = atof(c[3])+0.5;
if(atof(c[3])<1) mpg123_leavePlay = 1;
mpg123_lastFrame = time(NULL);
if(mpg123_stopAtEnd && atof(c[4])<1) {
mpg123_stopAtEnd = 0;
mpg123stop(stderr);
}
}
else if(0==strcmp(c[0],"@P")) {
if(mpg123_state==MPG123_STATE_PLAY && atoi(c[1])==MPG123_STATE_STOP) {
if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_STOP) {
if(!mpg123_leavePlay) {
mpg123_leavePlay=1;
mpg123_error = 1;
}
else {
nextSongInPlaylist(stderr);
}
}
else if(mpg123_state==MPG123_STATE_PLAY && atoi(c[1])==MPG123_STATE_PAUSE) {
else if(mpg123_state==PLAYER_STATE_PLAY && atoi(c[1])==PLAYER_STATE_PAUSE) {
mpg123_leavePause = 1;
}
else if(mpg123_state==MPG123_STATE_PAUSE && atoi(c[1])==MPG123_STATE_PLAY) {
else if(mpg123_state==PLAYER_STATE_PAUSE && atoi(c[1])==PLAYER_STATE_PLAY) {
mpg123_leavePause = 1;
}
//mpg123_state = atoi(c[1]);
......@@ -329,16 +329,14 @@ int mpg123processMessages() {
}
}
}
if(mpg123gotErrors()) mpg123_error = 1;
if(mpg123_stopAtEnd) {
mpg123_elapsedTime = mpg123_reportedElapsedTime+time(NULL)-mpg123_lastFrame;
}
else {
mpg123_elapsedTime = mpg123_reportedElapsedTime;
if(mpg123gotErrors()) {
mpg123_error = 1;
mpg123_leavePlay = 1;
}
if(mpg123_stopAtEnd && mpg123_elapsedTime>mpg123_totalTime) {
mpg123_stopAtEnd = 0;
mpg123_elapsedTime = mpg123_reportedElapsedTime+time(NULL)-mpg123_lastFrame;
if(!mpg123_error && mpg123_leavePlay && mpg123_elapsedTime>=mpg123_totalTime) {
mpg123stop(stderr);
nextSongInPlaylist(stderr);
}
}
......@@ -350,6 +348,18 @@ void mpg123kill() {
//kill(-1,SIGKILL);
/* old new stuff to try */
if(mpg123_pid>0) system("killall -KILL mpg123");
mpg123_state = MPG123_STATE_STOP;
mpg123_state = PLAYER_STATE_STOP;
mpg123_sigHandler(SIGCHLD);
}
int getMpg123elapsedTime() {
return mpg123_elapsedTime;
}
int getMpg123totalTime() {
return mpg123_totalTime;
}
int getMpg123state() {
return mpg123_state;
}
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -23,18 +21,6 @@
#include <stdio.h>
#define MPG123_STATE_STOP 0
#define MPG123_STATE_PAUSE 1
#define MPG123_STATE_PLAY 2
#define MPG123_KILL 1
#define MPG123_NOKILL 0
extern int mpg123_totalTime;
extern int mpg123_elapsedTime;
extern int mpg123_state;
extern int mpg123_stopAtEnd;
void mpg123_sigHandler(int signal);
int mpg123play(FILE * fp, char * file);
......@@ -47,4 +33,10 @@ void mpg123kill();
int mpg123processMessages();
int getMpg123totalTime();
int getMpg123elapsedTime();
int getMpg123state();
#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_OGG
#include "ogg.h"
#include "command.h"
#include "interface.h"
#include "playlist.h"
#include "ls.h"
#include "utils.h"
#include "player.h"
#include "listen.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <vorbis/vorbisfile.h>
#include <ao/ao.h>
#define OGG_ERROR "@ERROR"
#define OGG_START "@START"
#define OGG_TIME "@TIME"
#define OGG_DONE "@DONE"
#define OGG_PAUSE_GOT "@PAUSE_GOT"
#define OGG_STOP "stop"
#define OGG_PAUSE "pause"
#define INPUT_BUFFER_SIZE 80
#define MAX_BUFFER_LENGTH 1024
char pcmout[64];
char input[INPUT_BUFFER_SIZE+1];
int ogg_pid = 0;
int ogg_state = PLAYER_STATE_STOP;
int ogg_elapsedTime = 0;
int ogg_totalTime = 0;
int ogg_send = -1;
int ogg_recv = -1;
int ogg_leavePlay = 1;
int ogg_leavePause = 1;
char ogg_buffer[MAX_BUFFER_LENGTH+1];
int ogg_bufferLength = 0;
int ogg_GO(char * file, FILE * in, FILE * out) {
OggVorbis_File vf;
int eof=0;
int current_section;
ao_device *device;
ao_sample_format format;
int default_driver;
FILE * oggfp;
int pause=0;
long ret;
float last_tell = 0;
ao_initialize();
default_driver = ao_default_driver_id();
if(!(oggfp = fopen(file,"r")) || ov_open(oggfp, &vf, NULL, 0) < 0) {
fprintf(out,"%s Input does not appear to be an Ogg bitstream.\n",OGG_ERROR);
fflush(out);
return -1;
}
{
vorbis_info *vi=ov_info(&vf,-1);
format.bits = 16;
format.channels = vi->channels;
format.rate = vi->rate;
format.byte_format = AO_FMT_LITTLE;
}
device = ao_open_live(default_driver,&format,NULL);
if(device == NULL) {
fprintf(out, "%s Error opening device.\n",OGG_ERROR);
fflush(out);
return -1;
}
fprintf(out,"%s\n",OGG_START);
fprintf(out,"%s %f %f\n",OGG_TIME,last_tell,ov_time_total(&vf,-1));
while(!eof) {
if(!pause) ret=ov_read(&vf,pcmout,sizeof(pcmout),0,2,1,&current_section);
if(ret==0) {
eof=1;
}
else if(ret<0) {
}
else if(!pause) {
ao_play(device,pcmout,sizeof(pcmout));
if(ov_time_tell(&vf)-last_tell>=0.2) {
last_tell = ov_time_tell(&vf);
fprintf(out,"%s %f %f\n",OGG_TIME,last_tell,ov_time_total(&vf,-1));
fflush(out);
}
}
{
static fd_set fds;
static struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 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(OGG_STOP,input)==0) {
eof=1;
}
else if(strcasecmp(OGG_PAUSE,input)==0) {
fprintf(out,"%s\n",OGG_PAUSE_GOT);
fflush(out);
pause = !pause;;
}
}
}
if(pause) usleep(1000);
}
ao_close(device);
ao_shutdown();
ov_clear(&vf);
fprintf(out,"%s\n",OGG_DONE);
return 0;
}
void ogg_sigHandler(int signal) {
if(signal==SIGCHLD) {
wait3(NULL,WNOHANG,NULL);
ogg_pid = 0;
close(ogg_recv);
close(ogg_send);
ogg_leavePause = 1;
if(ogg_state==PLAYER_STATE_PLAY) {
ogg_state = PLAYER_STATE_STOP;
ogg_leavePlay = 1;
fprintf(stderr,"ogg died while playing\n");
nextSongInPlaylist(stderr);
}
else ogg_state = PLAYER_STATE_STOP;
}
}
int oggInit(char * file) {
int fd_send[2], fd_recv[2];
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_send)<0) {
fprintf(stderr,"%s ogg Problems socketpair'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(socketpair(AF_UNIX,SOCK_STREAM,0,fd_recv)<0) {
fprintf(stderr,"%s ogg Problems socketpair()'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
signal(SIGPIPE,SIG_IGN);
signal(SIGCHLD,ogg_sigHandler);
ogg_pid = fork();
if(ogg_pid==0) {
FILE * in;
FILE * out;
close(listenSocket);
closeAllInterfaces();
close(fd_send[0]);
close(fd_recv[0]);
in = fdopen(fd_send[1],"r");
out = fdopen(fd_recv[1],"w");
if(ogg_GO(file,in,out)<0) {
fprintf(stderr,"%s Problems spawning ogg\n",COMMAND_RESPOND_ERROR);
fclose(in);
fclose(out);
exit(-1);
}
fclose(in);
fclose(out);
exit(0);
}
else if(ogg_pid<0) {
fprintf(stderr,"%s ogg Problems fork()'ing\n",COMMAND_RESPOND_ERROR);
ogg_pid = 0;
close(fd_send[0]);
close(fd_send[1]);
close(fd_recv[0]);
close(fd_recv[1]);
return -1;
}
close(fd_send[1]);
close(fd_recv[1]);
ogg_send = fd_send[0];
ogg_recv = fd_recv[0];
return 0;
}
int oggPlay(FILE * fp, char * file) {
if(fp==NULL) fp=stderr;
if(!isOgg(file)) {
fprintf(fp,"%s \"%s\" is not a ogg\n",file,COMMAND_RESPOND_ERROR);
return -1;
}
if(oggStop(fp)<0) return -1;
if(oggInit(file)<0) {
fprintf(fp,"%s problems init'ing ogg\n",COMMAND_RESPOND_ERROR);
return -1;
}
if(ogg_pid<=0) {
printf("OOOPS, ogg_pid = %i\n",ogg_pid);
}
ogg_leavePlay = 0;
ogg_state = PLAYER_STATE_PLAY;
/*sleep until status is updated*/
while(!ogg_leavePlay) {
oggProcessMessages();
usleep(1000);
}
return 0;
}
int oggStop(FILE * fp) {
if(ogg_pid>0) {
char string[1024];
ogg_state = PLAYER_STATE_STOP;
sprintf(string,"%s\n",OGG_STOP);
if(write(ogg_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
return -1;
}
waitpid(ogg_pid,NULL,0);
}
ogg_state = PLAYER_STATE_STOP;
return 0;
}
int oggPause(FILE * fp) {
char string[1024];
if(ogg_pid>0) {
ogg_leavePause = 0;
sprintf(string,"%s\n",OGG_PAUSE);
if(write(ogg_send,string,strlen(string))<0) {
fprintf(fp,"%s problems write'ing\n",COMMAND_RESPOND_ERROR);
}
if(ogg_state==PLAYER_STATE_PLAY) {
ogg_state = PLAYER_STATE_PAUSE;
}
else if(ogg_state==PLAYER_STATE_PAUSE) {
ogg_state = PLAYER_STATE_PLAY;
}
while(!ogg_leavePause) {
oggProcessMessages();
usleep(1000);
}
}
return 0;
}
int oggReadline() {
fd_set fdsr;
struct timeval tv;
FD_ZERO(&fdsr);
FD_SET(ogg_recv,&fdsr);
tv.tv_sec = tv.tv_usec = 0;
if(select(ogg_recv+1,&fdsr,NULL,NULL,&tv)==1) {
int rc;
while(1) {
rc = read(ogg_recv,ogg_buffer+ogg_bufferLength,1);
if(rc<=0) {
return -1;
}
if(ogg_buffer[ogg_bufferLength]=='\0' || ogg_buffer[ogg_bufferLength]=='\n' || ogg_bufferLength == MAX_BUFFER_LENGTH) {
ogg_buffer[ogg_bufferLength] = '\0';
ogg_bufferLength = 0;
return -1;
}
ogg_bufferLength++;
}
}
return 0;
}
int oggProcessMessages() {
if(ogg_pid>0) {
while(oggReadline()) {
char * c[4];
c[0] = strtok(ogg_buffer," ");
if(c[0]) {
if(0==strcmp(c[0],OGG_TIME)) {
c[1] = strtok(NULL," ");
c[2] = strtok(NULL," ");
ogg_totalTime = atof(c[2])+0.5;
ogg_elapsedTime = atof(c[1])+0.5;
}
else if(0==strcmp(c[0],OGG_DONE)) {
wait3(NULL,WNOHANG,NULL);
nextSongInPlaylist(stderr);
}
else if(0==strcmp(c[0],OGG_ERROR)) {
fprintf(stderr,"ogg error: %s\n",c[1]);
}
else if(0==strcmp(c[0],OGG_START)) {
ogg_leavePlay = 1;
}
else if(0==strcmp(c[0],OGG_PAUSE_GOT)) {
ogg_leavePause = 1;
}
}
}
}
return 0;
}
void oggKill() {
if(ogg_pid>0) {
kill(ogg_pid,SIGKILL);
wait3(NULL,WNOHANG,NULL);
}
}
int getOggElapsedTime() {
return ogg_elapsedTime;
}
int getOggTotalTime() {
return ogg_totalTime;
}
int getOggState() {
return ogg_state;
}
#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 OGG_H
#define OGG_H
#include <stdio.h>
#define OGG_STATE_STOP 0
#define OGG_STATE_PAUSE 1
#define OGG_STATE_PLAY 2
void ogg_sigHandler(int signal);
int oggPlay(FILE * fp, char * file);
int oggPause(FILE * fp);
int oggStop(FILE * fp);
void oggKill();
int oggProcessMessages();
int getOggTotalTime();
int getOggElapsedTime();
int getOggState();
#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 "player.h"
#include "mpg123.h"
#ifdef HAVE_OGG
#include "ogg.h"
#endif
#include "command.h"
#include "interface.h"
#include "playlist.h"
#include "ls.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#define PLAYER_NONE 0
#define PLAYER_MPG123 1
#define PLAYER_OGG 2
int player_type = PLAYER_NONE;
int playerPlay(FILE * fp, char * file) {
if(playerStop(fp)<0) return -1;
if(isMp3(file)) {
player_type = PLAYER_MPG123;
return mpg123play(fp,file);
}
#ifdef HAVE_OGG
else if(isOgg(file)) {
player_type = PLAYER_OGG;
return oggPlay(fp,file);
}
#endif
fprintf(fp,"%s problems with file\n",COMMAND_RESPOND_ERROR);
return -1;
}
int playerStop(FILE * fp) {
if(player_type==PLAYER_MPG123) {
if(mpg123stop(fp)<0) return -1;
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
if(oggStop(fp)<0) return -1;
}
#endif
player_type = PLAYER_NONE;
return 0;
}
int playerPause(FILE * fp) {
if(player_type==PLAYER_MPG123) {
if(mpg123pause(fp)<0) return -1;
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
if(oggPause(fp)<0) return -1;
}
#endif
return 0;
}
void playerKill() {
mpg123kill();
#ifdef HAVE_OGG
oggKill();
#endif
}
void playerProcessMessages() {
mpg123processMessages();
#ifdef HAVE_OGG
oggProcessMessages();
#endif
}
int getPlayerTotalTime() {
if(player_type==PLAYER_MPG123) {
return getMpg123totalTime();
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
return getOggTotalTime();
}
#endif
return 0;
}
int getPlayerElapsedTime() {
if(player_type==PLAYER_MPG123) {
return getMpg123elapsedTime();
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
return getOggElapsedTime();
}
#endif
return 0;
}
int getPlayerState() {
if(player_type==PLAYER_MPG123) {
return getMpg123state();
}
#ifdef HAVE_OGG
else if(player_type==PLAYER_OGG) {
return getOggState();
}
#endif
return 0;
}
/* 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 PLAYER_H
#define PLAYER_H
#include <stdio.h>
#define PLAYER_STATE_STOP 0
#define PLAYER_STATE_PAUSE 1
#define PLAYER_STATE_PLAY 2
extern int player_totalTime;
extern int player_elapsedTime;
extern int player_state;
int playerPlay(FILE * fp, char * file);
int playerPause(FILE * fp);
int playerStop(FILE * fp);
void playerKill();
void playerProcessMessages();
int getPlayerTotalTime();
int getPlayerElapsedTime();
int getPlayerState();
#endif
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -19,7 +17,7 @@
*/
#include "playlist.h"
#include "mpg123.h"
#include "player.h"
#include "command.h"
#include "ls.h"
#include "tag.h"
......@@ -42,7 +40,7 @@ void initPlaylist() {
}
int checkThatPlaylistIsStopped(FILE * fp) {
if(mpg123_state!=MPG123_STATE_STOP) {
if(getPlayerState()!=PLAYER_STATE_STOP) {
fprintf(fp,"%s playlist is not stopped\n",COMMAND_RESPOND_ERROR);
return -1;
}
......@@ -53,7 +51,7 @@ int checkThatPlaylistIsStopped(FILE * fp) {
int clearPlaylist(FILE * fp) {
int i;
if(mpg123stop(fp)<0) return -1;
if(playerStop(fp)<0) return -1;
for(i=0;i<playlist.length;i++) {
freeSong(playlist.songs[i]);
......@@ -65,7 +63,7 @@ int clearPlaylist(FILE * fp) {
}
int addToPlaylist(FILE * fp, char * file) {
if(!isMp3(file)) {
if(!isMusic(file)) {
fprintf(fp,"%s \"%s\" is not a mp3\n",COMMAND_RESPOND_ERROR,file);
return -1;
}
......@@ -126,6 +124,7 @@ void swapSongs(int song1, int song2) {
int deleteFromPlaylist(FILE * fp, int song) {
int i;
int state = getPlayerState();
if(song<0) {
fprintf(fp,"%s need a positive interger\n",COMMAND_RESPOND_ERROR);
......@@ -143,11 +142,11 @@ int deleteFromPlaylist(FILE * fp, int song) {
playlist.length--;
if(mpg123_state!=MPG123_STATE_STOP && playlist.current==song) {
if(playlist.current>=playlist.length) return mpg123stop(fp);
if(state!=PLAYER_STATE_STOP && playlist.current==song) {
if(playlist.current>=playlist.length) return playerStop(fp);
else return playPlaylist(fp,playlist.current);
}
else if(mpg123_state!=MPG123_STATE_STOP && playlist.current>song) {
else if(state!=PLAYER_STATE_STOP && playlist.current>song) {
playlist.current--;
}
......@@ -164,24 +163,24 @@ int playPlaylist(FILE * fp, int song) {
return -1;
}
if(mpg123stop(fp)<0) return -1;
if(playerStop(fp)<0) return -1;
playlist.current = song;
return mpg123play(fp,(playlist.songs[song])->file);
return playerPlay(fp,(playlist.songs[song])->file);
}
int nextSongInPlaylist(FILE * fp) {
while(playlist.current<playlist.length-1) {
playlist.current++;
if(mpg123play(fp,(playlist.songs[playlist.current])->file)==0) return 0;
if(playerPlay(fp,(playlist.songs[playlist.current])->file)==0) return 0;
}
if(playlist.current==playlist.length-1) {
/*if(playlist.current==playlist.length-1) {
mpg123_stopAtEnd = 1;
}
else {
mpg123stop(fp); /*stop and kill mpg123*/
}
mpg123stop(fp);
}*/
return 0;
}
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -40,8 +38,16 @@ Song * newSong(char * file) {
Song * song = malloc(sizeof(Song));
song->file = strdup(file);
song->tag = id3Dup(file);
#ifdef HAVE_OGG
if((song->mtime = isOgg(file))) {
song->tag = oggCommentDup(file);
}
else
#endif
{
song->mtime = isMp3(file);
song->tag = id3Dup(file);
}
return song;
}
......@@ -59,7 +65,7 @@ SongList * newSongList() {
Song * addSongToList(SongList * list, char * key, char * file) {
Song * song;
if(isMp3(file)) {
if(isMusic(file)) {
song = newSong(file);
}
else {
......@@ -168,8 +174,13 @@ void readSongInfoIntoList(FILE * fp, SongList * list) {
int updateSongInfo(Song * song) {
if(song->tag) freeMpdTag(song->tag);
if(!(song->mtime = isMp3(song->file))) return -1;
song->tag = id3Dup(song->file);
if((song->mtime = isMp3(song->file))) song->tag = id3Dup(song->file);
#ifdef HAVE_OGG
else if((song->mtime = isOgg(song->file))) {
song->tag = oggCommentDup(song->file);
}
#endif
else return -1;
return 0;
}
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -179,8 +177,6 @@ int searchForSongsInTitleTable(FILE * fp,char * search) {
char * dup;
char * dupSearch = strDupToUpper(search);
if(!song->tag || !song->tag->title) return -1;
while(node) {
song = (Song *)node->data;
dup = strDupToUpper(song->tag->title);
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -23,6 +21,9 @@
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_OGG
#include <vorbis/vorbisfile.h>
#endif
#include "id3v2lib/lib_id3v2.3.h"
#include "id3v2lib/lib_id3v2.2.h"
......@@ -90,6 +91,58 @@ MpdTag * id3Dup(char * file) {
return ret;
}
#ifdef HAVE_OGG
MpdTag * oggCommentDup(char * file) {
MpdTag * ret = NULL;
FILE * fp;
OggVorbis_File vf;
char ** comments;
char * temp;
char * s1;
char * s2;
if(!(fp = fopen(file,"r"))) return NULL;
if(ov_open(fp,&vf,NULL,0)<0) return NULL;
comments = ov_comment(&vf,-1)->user_comments;
while(*comments) {
temp = strdup(*comments);
s1 = strtok(temp,"=");
s2 = strtok(NULL,"=");
if(0==strcasecmp(s1,"artist")) {
if(!ret) ret = newMpdTag();
if(!ret->artist && s2) ret->artist = strdup(s2);
}
else if(0==strcasecmp(s1,"title")) {
if(!ret) ret = newMpdTag();
if(!ret->title && s2) ret->title = strdup(s2);
}
else if(0==strcasecmp(s1,"album")) {
if(!ret) ret = newMpdTag();
if(!ret->album && s2) ret->album = strdup(s2);
}
else if(0==strcasecmp(s1,"tracknumber")) {
if(!ret) ret = newMpdTag();
if(!ret->track && s2) ret->track = strdup(s2);
}
free(temp);
++comments;
}
ov_clear(&vf);
if(ret) {
if(!ret->artist) ret->artist = strdup("");
if(!ret->album) ret->album = strdup("");
if(!ret->title) ret->title = strdup("");
if(!ret->track) ret->track = strdup("");
}
return ret;
}
#endif
MpdTag * newMpdTag() {
MpdTag * ret = malloc(sizeof(MpdTag));
ret->album = NULL;
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......@@ -36,6 +34,8 @@ void freeMpdTag(MpdTag * tag);
MpdTag * id3Dup(char * file);
MpdTag * oggCommentDup(char * file);
void printMpdTag(FILE * fp, MpdTag * tag);
#endif
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
......@@ -2,8 +2,6 @@
* (c)2003 by Warren Dukes (shank@mercury.chem.pitt.edu)
* This project's homepage is: http://musicpd.sourceforge.net
*
* 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
......
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