gjay-0.3.2/ 0000755 0001750 0001750 00000000000 11546012710 007444 5 0000000 0000000 gjay-0.3.2/mp3.h 0000644 0001750 0001750 00000005044 11432427412 010242 0000000 0000000 /*
* Gjay - Gtk+ DJ music playlist creator
* Copyright (C) 2002,2003 Chuck Groom
* Copyright (C) 2010 Craig Small
*
* 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, 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, see .
*
* MP3 header information comes from mp3info package's mp3tech.h:
* Copyright (C) 2000-2006 Cedr Cedric Tefft
* which is licensed under version 2 of the GNU General Public License.
*
* mp3tech.h is based in part on:
* MP3Info 0.5 by Ricardo Cerqueira
* MP3Stat 0.9 by Ed Sweetman and
* Johannes Overmann
*/
#include
#include
#include
#include
#include
#include
enum VBR_REPORT { VBR_VARIABLE, VBR_AVERAGE, VBR_MEDIAN };
enum SCANTYPE { SCAN_NONE, SCAN_QUICK, SCAN_FULL };
typedef struct {
unsigned long sync;
unsigned int version;
unsigned int layer;
unsigned int crc;
unsigned int bitrate;
unsigned int freq;
unsigned int padding;
unsigned int extension;
unsigned int mode;
unsigned int mode_extension;
unsigned int copyright;
unsigned int original;
unsigned int emphasis;
} mp3header;
typedef struct {
char title[31];
char artist[31];
char album[31];
char year[5];
char comment[31];
unsigned char track[1];
unsigned char genre[1];
} id3tag;
typedef struct {
char *filename;
FILE *file;
off_t datasize;
int header_isvalid;
mp3header header;
int id3_isvalid;
id3tag id3;
int vbr;
float vbr_average;
int seconds;
int frames;
int badframes;
} mp3info;
gboolean
read_mp3_file_type( gchar * path,
gint * length,
gchar ** title,
gchar ** artist,
gchar ** album);
int get_mp3_info( mp3info *mp3,
int scantype,
int fullscan_vbr);
int get_id3_tags( FILE * fp,
gchar ** title,
gchar ** artist,
gchar ** album);
gjay-0.3.2/flac.c 0000644 0001750 0001750 00000016304 11432427714 010451 0000000 0000000 /*
* Gjay - Gtk+ DJ music playlist creator
* Copyright (C) 2010 Craig Small
* flac.c - flac file handling
*
* 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, 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, see .
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_FLAC_METADATA_H
#include
#include
#include
#include
#include
#include
#include "flac.h"
#include "gjay.h"
#include "util.h"
#include "i18n.h"
/* the functions */
FLAC__Metadata_Chain* (*gjflac_metadata_chain_new)(void);
FLAC__bool (*gjflac_metadata_chain_read)(FLAC__Metadata_Chain *chain, const char *filename);
FLAC__Metadata_ChainStatus (*gjflac_metadata_chain_status)(FLAC__Metadata_Chain *chain);
void (*gjflac_metadata_chain_delete) (FLAC__Metadata_Chain *chain);
FLAC__Metadata_Iterator* (*gjflac_metadata_iterator_new)(void);
void (*gjflac_metadata_iterator_init)(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain);
FLAC__StreamMetadata * (*gjflac_metadata_iterator_get_block)(FLAC__Metadata_Iterator *iterator);
FLAC__bool (*gjflac_metadata_iterator_next)(FLAC__Metadata_Iterator *iterator);
void (*gjflac_metadata_iterator_delete) (FLAC__Metadata_Iterator *iterator);
gboolean
gjay_flac_dlopen(void) {
void * lib;
lib = dlopen("libFLAC.so.8", RTLD_GLOBAL | RTLD_LAZY);
if (!lib) {
return FALSE;
}
/* Clear any error first */
dlerror();
if ( (gjflac_metadata_chain_new =
gjay_dlsym(lib, "FLAC__metadata_chain_new")) == NULL)
return FALSE;
if ( (gjflac_metadata_chain_read =
gjay_dlsym(lib, "FLAC__metadata_chain_read")) == NULL)
return FALSE;
if ( (gjflac_metadata_chain_status =
gjay_dlsym(lib, "FLAC__metadata_chain_status")) == NULL)
return FALSE;
if ( (gjflac_metadata_chain_delete =
gjay_dlsym(lib, "FLAC__metadata_chain_delete")) == NULL)
return FALSE;
if ( (gjflac_metadata_iterator_new =
gjay_dlsym(lib, "FLAC__metadata_iterator_new")) == NULL)
return FALSE;
if ( (gjflac_metadata_iterator_init =
gjay_dlsym(lib, "FLAC__metadata_iterator_init")) == NULL)
return FALSE;
if ( (gjflac_metadata_iterator_get_block =
gjay_dlsym(lib, "FLAC__metadata_iterator_get_block")) == NULL)
return FALSE;
if ( (gjflac_metadata_iterator_next =
gjay_dlsym(lib, "FLAC__metadata_iterator_next")) == NULL)
return FALSE;
if ( (gjflac_metadata_iterator_delete =
gjay_dlsym(lib, "FLAC__metadata_iterator_delete")) == NULL)
return FALSE;
return TRUE;
}
gboolean
read_flac_file_type( gchar * path,
gint * length,
gchar ** title,
gchar ** artist,
gchar ** album)
{
FILE *fp;
int i;
FLAC__Metadata_Chain *chain;
assert(gjflac_metadata_chain_new);
if ( (fp = g_fopen(path, "r")) == NULL)
return FALSE;
if ( (chain = (*gjflac_metadata_chain_new)()) == 0)
return FALSE;
if (!(*gjflac_metadata_chain_read)(chain, path)) {
if (verbosity > 2)
g_warning(_("Unable to read FLAC metadata for file %s\n"), path);
return FALSE;
}
// Loop through metadata
FLAC__Metadata_Iterator *iterator = (*gjflac_metadata_iterator_new)();
FLAC__StreamMetadata *block;
FLAC__bool ok = true;
unsigned block_number;
if (0 == iterator) {
g_warning(_("Out of memory creating FLAC iterator.\n"));
return FALSE;
}
(*gjflac_metadata_iterator_init)(iterator, chain);
block_number = 0;
do {
block = (*gjflac_metadata_iterator_get_block)(iterator);
ok &= (0 != block);
if (!ok)
g_warning (_("Could not get block from FLAC chain for %s\n"), path);
else {
// Parse metadata
switch(block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
// Time is samples / samplerate
* length = block->data.stream_info.total_samples / block->data.stream_info.sample_rate;
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
for (i = 0; i < block->data.vorbis_comment.num_comments; i++) {
char* comment = malloc (block->data.vorbis_comment.comments[i].length + 1);
memcpy (comment, block->data.vorbis_comment.comments[i].entry, block->data.vorbis_comment.comments[i].length);
comment[block->data.vorbis_comment.comments[i].length] = '\0';
//printf ("comment[%u]:%s - %d\n", i, comment, block->data.vorbis_comment.comments[i].length);
if (block->data.vorbis_comment.comments[i].length > 5) {
if (strncasecmp("ARTIST=", comment, strlen("ARTIST=")) == 0) {
char* text = malloc (block->data.vorbis_comment.comments[i].length - strlen("ARTIST=") + 1);
int j;
for (j = 0; j < block->data.vorbis_comment.comments[i].length - strlen("ARTIST=") + 1; j++) {
text[j] = block->data.vorbis_comment.comments[i].entry[j + strlen("ARTIST=")];
}
text[block->data.vorbis_comment.comments[i].length - strlen("ARTIST=")] = '\0';
//printf ("ARTIST: %s\n", text);
*artist = strdup_to_utf8(text);
free (text);
}
if (strncasecmp("TITLE=", comment, strlen("TITLE=")) == 0) {
char* text = malloc (block->data.vorbis_comment.comments[i].length - strlen("TITLE=") + 1);
int j;
for (j = 0; j < block->data.vorbis_comment.comments[i].length - strlen("TITLE=") + 1; j++) {
text[j] = block->data.vorbis_comment.comments[i].entry[j + strlen("TITLE=")];
}
text[block->data.vorbis_comment.comments[i].length - strlen("TITLE=")] = '\0';
//printf ("TITLE: %s\n", text);
*title = strdup_to_utf8(text);
free (text);
}
if (strncasecmp("ALBUM=", comment, strlen("ALBUM=")) == 0) {
char* text = malloc (block->data.vorbis_comment.comments[i].length - strlen("ALBUM=") + 1);
int j;
for (j = 0; j < block->data.vorbis_comment.comments[i].length - strlen("ALBUM=") + 1; j++) {
text[j] = block->data.vorbis_comment.comments[i].entry[j + strlen("ALBUM=")];
}
text[block->data.vorbis_comment.comments[i].length - strlen("ALBUM=")] = '\0';
//printf ("ALBUM: %s\n", text);
*album = strdup_to_utf8(text);
free (text);
}
}
free (comment);
}
break;
default:
// Ignore all other metadata blocks
break;
}
block_number++;
}
} while (ok && (*gjflac_metadata_iterator_next)(iterator));
(*gjflac_metadata_iterator_delete) (iterator);
(gjflac_metadata_chain_delete) (chain);
fclose(fp);
return TRUE;
}
#endif /* HAVE_FLAC_METADATA_H */
gjay-0.3.2/rgbhsv.h 0000644 0001750 0001750 00000002222 11432426564 011040 0000000 0000000 /*
* Gjay - Gtk+ DJ music playlist creator
* Copyright (C) 2002 Chuck Groom
* Copyright (C) 2010 Craig Small
*
* 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, 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, see .
*/
#ifndef _RGBHSB_H_
#define _RGBHSB_H_
#include
typedef struct {float R, G, B;} RGB;
typedef struct {float H, S, V;} HSV;
typedef struct {float H, B;} HB;
HSV rgb_to_hsv ( RGB rgb );
RGB hsv_to_rgb ( HSV hsv );
guint32 rgb_to_hex ( RGB rgb );
HSV hb_to_hsv ( HB hb );
HB hsv_to_hb ( HSV hsv );
int get_named_color (char * str, RGB * rgb );
char * known_colors (void);
#endif
gjay-0.3.2/play_audacious.c 0000644 0001750 0001750 00000011055 11546007146 012543 0000000 0000000 /*
* Gjay - Gtk+ DJ music playlist creator
* play_audacious.c : Output for Audacious
* Copyright (C) 2010-2011 Craig Small
*
* 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, 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, see .
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include
#include
#include
#include
#include
#include
#include
#include "gjay.h"
#include "songs.h"
#include "dbus.h"
#include "i18n.h"
#include "ui.h"
#include "play_audacious.h"
static void audacious_connect(void);
/* dlym'ed functions */
gint (*gjaud_get_playlist_pos)(DBusGProxy *proxy);
gchar *(*gjaud_get_playlist_file)(DBusGProxy *proxy, guint pos);
void (*gjaud_stop)(DBusGProxy *proxy);
void (*gjaud_playlist_clear)(DBusGProxy *proxy);
void (*gjaud_playlist_add_url_string)(DBusGProxy *proxy, gchar *string);
void (*gjaud_play)(DBusGProxy *proxy);
/* public functions */
gboolean
audacious_init(void)
{
void *lib;
if ( (lib = dlopen("libaudclient.so.2", RTLD_GLOBAL | RTLD_LAZY)) == NULL)
{
gjay_error_dialog(_("Unable to open audcious client library, defaulting to no play."));
return FALSE;
}
if ( (gjaud_get_playlist_pos = gjay_dlsym(lib, "audacious_remote_get_playlist_pos")) == NULL)
return FALSE;
if ( (gjaud_get_playlist_file = gjay_dlsym(lib, "audacious_remote_get_playlist_file")) == NULL)
return FALSE;
if ( (gjaud_stop = gjay_dlsym(lib, "audacious_remote_stop")) == NULL)
return FALSE;
if ( (gjaud_play = gjay_dlsym(lib, "audacious_remote_play")) == NULL)
return FALSE;
if ( (gjaud_playlist_clear = gjay_dlsym(lib, "audacious_remote_playlist_clear")) == NULL)
return FALSE;
if ( (gjaud_playlist_add_url_string = gjay_dlsym(lib, "audacious_remote_playlist_add_url_string")) == NULL)
return FALSE;
gjay->player_get_current_song = &audacious_get_current_song;
gjay->player_is_running = &audacious_is_running;
gjay->player_play_files = &audacious_play_files;
gjay->player_start = &audacious_start;
return TRUE;
}
gboolean
audacious_start(void)
{
GError *error = NULL;
GAppInfo *aud_app;
int i;
if ((aud_app = g_app_info_create_from_commandline(
AUDACIOUS_BIN,
"Audacious",
G_APP_INFO_CREATE_NONE,
&error)) == NULL)
{
g_warning(_("Cannot create audacious g_app: %s\n"), error->message);
g_error_free(error);
return FALSE;
}
error=NULL;
if (g_app_info_launch(aud_app, NULL, NULL, &error) == FALSE)
{
g_warning(_("Cannot launch audacious g_app: %s"), error->message);
g_error_free(error);
return FALSE;
}
/* Give it 3 tries */
for(i=1; i<= 3; i++)
{
if (audacious_is_running())
return TRUE;
sleep(1);
}
return FALSE;
}
gboolean
audacious_is_running(void)
{
return gjay_dbus_is_running(AUDACIOUS_DBUS_SERVICE);
}
song *
audacious_get_current_song(void) {
gchar *playlist_file;
gchar *uri;
gint pos;
song *s;
audacious_connect();
pos = (*gjaud_get_playlist_pos)(gjay->player_proxy);
playlist_file = (*gjaud_get_playlist_file)(gjay->player_proxy, pos);
if (playlist_file == NULL)
return NULL;
uri = g_filename_from_uri(playlist_file, NULL, NULL);
if (uri == NULL)
return NULL;
s = g_hash_table_lookup(gjay->song_name_hash, uri);
g_free(playlist_file);
g_free(uri);
return s;
}
void
audacious_play_files ( GList *list) {
GList *lptr = NULL;
gchar *uri = NULL;
audacious_connect();
(*gjaud_stop)(gjay->player_proxy);
(*gjaud_playlist_clear)(gjay->player_proxy);
for (lptr=list; lptr; lptr = g_list_next(lptr)) {
uri = g_filename_to_uri(lptr->data, NULL, NULL);
(*gjaud_playlist_add_url_string)(gjay->player_proxy, uri);
g_free(uri);
}
(*gjaud_play)(gjay->player_proxy);
}
/* static functions */
/* Connect and init audacious instance */
static void
audacious_connect(void)
{
if (gjay->player_proxy != NULL)
return;
gjay->player_proxy = dbus_g_proxy_new_for_name(gjay->connection,
AUDACIOUS_DBUS_SERVICE, AUDACIOUS_DBUS_PATH, AUDACIOUS_DBUS_INTERFACE);
}
gjay-0.3.2/README 0000644 0001750 0001750 00000002514 11545771627 010270 0000000 0000000 GJay v0.3.2
Copyright Chuck Groom, 2003
Copyright Craig Small 2010,2011
gjay.sourceforge.net
GJay (Gtk+ DJ) generates playlists across a collection of music (mp3,
ogg, wav) such that each song sounds good following the previous
song. Matches are based on both automatically analyzed song
characteristics (BPM, frequency) as well as user-assigned
categorizations (song 'color' and rating). It is ideal for DJs
planning a set list and home users wanting a non-random way to wander
large collections.
See http://gjay.sourceforge.net for help and more information.
GJay is released under the GPL (see COPYING).
BPM analysis code comes from Van Belle Werner's "bpmdj",
http://bpmdj.sourceforge.net/
Frequency analysis code comes from Daniel Franklin's "Spectromatic",
http://ieee.uow.edu.au/~daniel/software/spectromatic/
BUILD
-----
GJay uses the following programs:
mpg321
ogg123
audacious
GJay depends on the following libraries:
libgtk-2.0
libgsl
libgslcblas
libaudacious
GJay supports ogg if it's there (a soft dependancy):
libvorbis
libvorbisfile
To build GJay, you'll need the header files for libgsl, audacious, and Gtk2
and libvorbis-dev
The relevant Debian packages are:
mpg321 vorbis-tools audacious
libgtk2.0 libgsl0 libvorbis (Debian keeps mucking about with this name...)
libgtk1.2-dev audacious-dev libgsl0-dev
gjay-0.3.2/NEWS 0000644 0001750 0001750 00000000000 11324546543 010063 0000000 0000000 gjay-0.3.2/icons/ 0000755 0001750 0001750 00000000000 11546012710 010557 5 0000000 0000000 gjay-0.3.2/icons/icon_song.png 0000644 0001750 0001750 00000001224 11323061737 013170 0000000 0000000 PNG
IHDR ( ( &p