[xiph-cvs] cvs commit: vorbis-tools/ogg123 playlist.c playlist.h Makefile.am ogg123.c
Stan Seibert
volsung at xiph.org
Fri Jul 5 20:23:14 PDT 2002
volsung 02/07/05 20:23:14
Modified: ogg123 Makefile.am ogg123.c
Added: ogg123 playlist.c playlist.h
Log:
Playlist support. Now both files and directories can be specified on the
command line. Directories are recursively examined and files added to the
playlist.
Revision Changes Path
1.25 +3 -2 vorbis-tools/ogg123/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Makefile.am,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- Makefile.am 2002/07/02 16:45:15 1.24
+++ Makefile.am 2002/07/06 03:23:13 1.25
@@ -27,10 +27,11 @@
ogg123_SOURCES = audio.c buffer.c callbacks.c \
cfgfile_options.c cmdline_options.c \
file_transport.c format.c http_transport.c \
- ogg123.c oggvorbis_format.c status.c transport.c \
+ ogg123.c oggvorbis_format.c playlist.c \
+ status.c transport.c \
audio.h buffer.h callbacks.h compat.h \
cfgfile_options.h cmdline_options.h \
- format.h ogg123.h status.h transport.h
+ format.h ogg123.h playlist.h status.h transport.h
man_MANS = $(mans)
doc_DATA = $(docs)
<p><p>1.62 +53 -20 vorbis-tools/ogg123/ogg123.c
Index: ogg123.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/ogg123.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- ogg123.c 2002/06/02 03:07:11 1.61
+++ ogg123.c 2002/07/06 03:23:13 1.62
@@ -14,7 +14,7 @@
* *
********************************************************************
- last mod: $Id: ogg123.c,v 1.61 2002/06/02 03:07:11 volsung Exp $
+ last mod: $Id: ogg123.c,v 1.62 2002/07/06 03:23:13 volsung Exp $
********************************************************************/
@@ -28,6 +28,8 @@
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <locale.h>
#include "audio.h"
@@ -38,6 +40,7 @@
#include "format.h"
#include "transport.h"
#include "status.h"
+#include "playlist.h"
#include "compat.h"
#include "ogg123.h"
@@ -270,6 +273,11 @@
int main(int argc, char **argv)
{
int optind;
+ char **playlist_array;
+ playlist_t *list = playlist_create();
+ int items;
+ struct stat stat_buf;
+ int i;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -286,23 +294,39 @@
audio_play_arg.devices = options.devices;
audio_play_arg.stat_format = stat_format;
- /* Don't use status_message until after this point! */
- status_set_verbosity(options.verbosity);
+ /* Add remaining arguments to playlist */
+ for (i = optind; i < argc; i++) {
+ if (stat(argv[i], &stat_buf) == 0) {
+
+ if (S_ISDIR(stat_buf.st_mode)) {
+ if (playlist_append_directory(list, argv[i]) == 0)
+ fprintf(stderr,
+ _("Warning: Could not read directory %s.\n"), argv[i]);
+ } else {
+ playlist_append_file(list, argv[i]);
+ }
+ } else
+ fprintf(stderr,
+ _("Warning: Could not access %s.\n"), argv[i]);
- print_audio_devices_info(options.devices);
-
- /* Setup signal handlers and callbacks */
+ }
- ATEXIT (exit_cleanup);
- signal (SIGINT, signal_handler);
- signal (SIGTSTP, signal_handler);
- signal (SIGCONT, signal_handler);
/* Do we have anything left to play? */
- if (optind == argc) {
+ if (playlist_length(list) == 0) {
cmdline_usage();
exit(1);
+ } else {
+ playlist_array = playlist_to_array(list, &items);
+ playlist_destroy(list);
+ list = NULL;
}
+
+ /* Don't use status_message until after this point! */
+ status_set_verbosity(options.verbosity);
+
+ print_audio_devices_info(options.devices);
+
/* Setup buffer */
if (options.buffer_size > 0) {
@@ -324,21 +348,30 @@
srandom(time(NULL));
- for (i = optind; i < argc; i++) {
- int j = i + random() % (argc - i);
- char *temp = argv[i];
- argv[i] = argv[j];
- argv[j] = temp;
+ for (i = 0; i < items; i++) {
+ int j = i + random() % (items - i);
+ char *temp = playlist_array[i];
+ playlist_array[i] = playlist_array[j];
+ playlist_array[j] = temp;
}
}
- /* Play the files/streams */
+ /* Setup signal handlers and callbacks */
- while (optind < argc && !sig_request.exit) {
- play(argv[optind]);
- optind++;
+ ATEXIT (exit_cleanup);
+ signal (SIGINT, signal_handler);
+ signal (SIGTSTP, signal_handler);
+ signal (SIGCONT, signal_handler);
+
+
+ /* Play the files/streams */
+ i = 0;
+ while (i < items && !sig_request.exit) {
+ play(playlist_array[i]);
+ i++;
}
+ playlist_array_destroy(playlist_array, items);
exit (0);
}
<p><p>1.1 vorbis-tools/ogg123/playlist.c
Index: playlist.c
===================================================================
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
* by Stan Seibert <volsung at xiph.org> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: playlist.c,v 1.1 2002/07/06 03:23:13 volsung Exp $
********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include "playlist.h"
#include "i18n.h"
playlist_element_t *playlist_element_create(char *filename)
{
playlist_element_t *element = (playlist_element_t *)
malloc(sizeof(playlist_t));
if (element == NULL) {
fprintf(stderr,
_("Error: Out of memory in create_playlist_member().\n"));
exit(1);
}
if (filename == NULL)
element->filename = NULL;
else {
element->filename = strdup(filename);
if (element->filename == NULL) {
fprintf(stderr,
_("Error: Out of memory in create_playlist_member().\n"));
exit(1);
}
}
element->next = NULL;
return element;
}
<p>/* Only destroys the current node. Does not affect linked nodes. */
void playlist_element_destroy(playlist_element_t *element)
{
free(element->filename);
free(element);
}
<p><p>playlist_t *playlist_create()
{
playlist_t *list = (playlist_t *) malloc(sizeof(playlist_t));
if (list != NULL) {
list->head = playlist_element_create(NULL);
list->last = list->head;
}
return list;
}
<p>void playlist_destroy(playlist_t *list) {
playlist_element_t *next_element;
while (list->head != NULL) {
next_element = list->head->next;
playlist_element_destroy(list->head);
list->head = next_element;
}
free(list);
}
<p>/* All of the playlist_append_* functions return
1 if append was successful
0 if failure (either directory could not be accessed or playlist on disk
could not be opened)
*/
<p>/* Add this filename to the playlist. Filename will be strdup()'ed. Note
that this function will never fail. */
int playlist_append_file(playlist_t *list, char *filename)
{
list->last->next = playlist_element_create(filename);
list->last = list->last->next;
return 1; /* No way to fail */
}
/* Recursively adds files from the directory and subdirectories */
int playlist_append_directory(playlist_t *list, char *dirname)
{
DIR *dir;
int dir_len = strlen(dirname);
struct dirent *entry;
struct stat stat_buf;
char nextfile[NAME_MAX + 1];
dir = opendir(dirname);
if (dir == NULL) {
return 0;
}
entry = readdir(dir);
while (entry != NULL) {
int sub_len = strlen(entry->d_name);
/* Make sure full pathname is within limits and we don't parse the
relative directory entries. */
if (dir_len + sub_len + 1 < NAME_MAX
&& strcmp(entry->d_name, ".") != 0
&& strcmp(entry->d_name, "..") != 0 ) {
/* Build the new full pathname */
strcpy(nextfile, dirname);
strcat(nextfile, "/");
strcat(nextfile, entry->d_name);
if (stat(nextfile, &stat_buf) == 0) {
/* Decide what type of entry this is */
if (S_ISDIR(stat_buf.st_mode)) {
/* Recursively follow directories */
if ( playlist_append_directory(list, nextfile) == 0 ) {
fprintf(stderr,
_("Warning: Could not read directory %s.\n"),
nextfile);
}
} else {
/* Assume everything else is a file of some sort */
playlist_append_file(list, nextfile);
}
}
}
entry = readdir(dir);
}
closedir(dir);
return 1;
}
<p>/* Opens a file containing filenames, one per line, and adds them to the
playlist */
int playlist_append_from_file(playlist_t *list, char *playlist_filename)
{
FILE *fp;
char filename[NAME_MAX+1];
int length;
int i;
fp = fopen(playlist_filename, "r");
if (fp == NULL)
return 0;
while (!feof(fp)) {
fgets(filename, NAME_MAX+1 /* no, really! */, fp);
length = strlen(filename);
// Skip blank lines
for (i = 0; i < length && isspace(filename[i]); i++);
if (i == length)
continue;
// Crop off last \n if present
if (filename[length - 1] == '\n')
filename[length - 1] = '\0';
playlist_append_file(list, filename);
}
return 1;
}
<p>/* Return the number of items in the playlist */
int playlist_length(playlist_t *list)
{
int length;
playlist_element_t *element;
element = list->head;
length = 0; // don't count head node
while (element->next != NULL) {
length++;
element = element->next;
}
return length;
}
<p>/* Convert the playlist to an array of strings. Strings are deep copied.
Size will be set to the number of elements in the array. */
char **playlist_to_array(playlist_t *list, int *size)
{
char **array;
int i;
playlist_element_t *element;
*size = playlist_length(list);
array = calloc(*size, sizeof(char *));
if (array == NULL) {
fprintf(stderr,
_("Error: Out of memory in playlist_to_array().\n"));
exit(1);
}
for (i = 0, element = list->head->next;
i < *size;
i++, element = element->next) {
array[i] = strdup(element->filename);
if (array[i] == NULL) {
fprintf(stderr,
_("Error: Out of memory in playlist_to_array().\n"));
exit(1);
}
}
<p> return array;
}
<p>/* Deallocate array and all contained strings created by playlist_to_array. */
void playlist_array_destroy(char **array, int size)
{
int i;
for (i = 0; i < size; i++)
free(array[i]);
free(array);
}
<p><p>1.1 vorbis-tools/ogg123/playlist.h
Index: playlist.h
===================================================================
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2002 *
* by Kenneth C. Arnold <ogg at arnoldnet.net> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: playlist.h,v 1.1 2002/07/06 03:23:13 volsung Exp $
********************************************************************/
#ifndef __PLAYLIST_H__
#define __PLAYLIST_H__
typedef struct playlist_element_t {
char *filename;
struct playlist_element_t *next;
} playlist_element_t;
/* Actual playlist structure */
typedef struct playlist_t {
/* Linked list with empty head node */
playlist_element_t *head;
/* Keep track of this for speedy appends */
playlist_element_t *last;
} playlist_t;
playlist_t *playlist_create();
void playlist_destroy(playlist_t *list);
/* All of the playlist_append_* functions return
1 if append was successful
0 if failure (either directory could not be accessed or playlist on disk
could not be opened)
*/
<p>/* Add this filename to the playlist. Filename will be strdup()'ed. Note
that this function will never fail. */
int playlist_append_file(playlist_t *list, char *filename);
/* Recursively adds files from the directory and subdirectories */
int playlist_append_directory(playlist_t *list, char *dirname);
/* Opens a file containing filenames, one per line, and adds them to the
playlist */
int playlist_append_from_file(playlist_t *list, char *playlist_filename);
/* Return the number of items in the playlist */
int playlist_length(playlist_t *list);
/* Convert the playlist to an array of strings. Strings are deep copied.
Size will be set to the number of elements in the array. */
char **playlist_to_array(playlist_t *list, int *size);
/* Deallocate array and all contained strings created by playlist_to_array. */
void playlist_array_destroy(char **array, int size);
<p>#endif /* __PLAYLIST_H__ */
<p><p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list