Today, I put my first program onto my empeg. It's called "hello world" and you can guess what it does.

I also put my second program onto it. It's a bit more useful. It's designed to answer the question everybody asks you: how much music is there on your empeg? It only works on single-drive machines at present, but I include source so you can see how to fix that.

To use, just install it on $PATH in your player (e.g. in /empeg/bin) and run it with no arguments to see how long it would take to play your root playlist, or with a list of FIDs to measure those.

Here's the code (binary is attached):




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/limits.h>

#define FID_ROOTPLAYLIST 0x100

#define FIDS_DIR "/drive0/fids"
#define FIDS_FILE0_FORMAT FIDS_DIR"/%x0"
#define FIDS_FILE1_FORMAT FIDS_DIR"/%x1"

#define LINESZ 512

#define TYPE_TUNE 1
#define TYPE_PLAYLIST 2

#if 0
#define DEBUG0(s) fprintf(stderr, s);
#define DEBUG1(s, x) fprintf(stderr, s, x);
#endif

int measure_item(int playlist);
int measure_playlist(int playlist);


int main(int argc, char **argv) {

int playlist;
int duration; /* in milliseconds */
int total = 0;
int i;
char *numend;

if (argc <= 1) {
/* argument not supplied - measure root playlist */
total = duration = measure_item(FID_ROOTPLAYLIST);
printf("Root playlist: %d.%03d", duration/1000, duration%1000);
} else {
for (i = 1; i < argc; i++) {
/* Parse argument as hexadecimal FID */
playlist = (int)strtol(argv[ i], &numend, 16);
if (*numend) {
fprintf(stderr, "%s: Unrecognised argument %s\n", argv[ 0], argv[ i]);
fprintf(stderr, "Usage: %s [ fid...]\n", argv[ 0]);
exit(EXIT_FAILURE);
}
total += duration = measure_item(playlist);
printf("Playlist %5x: %d.%03d\n", playlist, duration/1000, duration%1000);
}
printf("Total: %d.%03d", total/1000, total%1000);
}

if (duration > 60000) {
int hours, minutes, seconds, millis;
millis = total % 1000;
total /= 1000;
seconds = total % 60;
minutes = total / 60 % 60;
hours = total / 3600;

printf(" (");
if (hours)
printf("%dh", hours);
if (minutes)
printf("%dm", minutes);
printf("%ds", seconds);
printf(")");
}
printf("\n");

return EXIT_SUCCESS;

}


/* Returns length of playlist or tune, in milliseconds. */
int measure_item(int playlist) {
char filename[ PATH_MAX+1];
char line[ LINESZ+1];
int duration = 0;
int type = 0;
FILE *f;

/* First, read the *1 file - is it a tune or a playlist? */
sprintf(filename, FIDS_FILE1_FORMAT, playlist/16);

/*DEBUG1("Opening %s\n", filename);*/
f = fopen(filename, "r");
if (f == NULL) {
perror(filename);
exit(EXIT_FAILURE);
}

while (fgets(line, LINESZ, f)) {
if (!strcmp(line, "type=tune\n")) {
type = TYPE_TUNE;
} else if (!strcmp(line, "type=playlist\n")) {
type = TYPE_PLAYLIST;
} else if (!strncmp(line, "duration=", 9)) {
duration = (int)strtol(line+9, NULL, 10);
}
}

if (ferror(f)) {
/* fgets failed, not at EOF */
perror(filename);
fclose(f);
exit(EXIT_FAILURE);
}

if (fclose(f)) {
perror(filename);
exit(EXIT_FAILURE);
}

switch (type) {
case TYPE_TUNE:
return duration;

case TYPE_PLAYLIST:
return measure_playlist(playlist);

default:
fprintf(stderr, "No type for %s", filename);
exit(EXIT_FAILURE);
}
}


int measure_playlist(int playlist) {
char filename[ PATH_MAX+1];
int fid;
int duration = 0;
FILE *f;

/* First, read the *0 file - this holds the child pointers. */
sprintf(filename, FIDS_FILE0_FORMAT, playlist/16);

f = fopen(filename, "rb");
if (f == NULL) {
perror(filename);
exit(EXIT_FAILURE);
}

while (1 == fread(&fid, 4, 1, f)) {
duration += measure_item(fid);
}

if (ferror(f)){
/* fread failed */
perror(filename);
fclose(f);
exit(EXIT_FAILURE);
}

if (fclose(f)) {
perror(filename);
exit(EXIT_FAILURE);
}

return duration;
}



--
Toby Speight


Attachments
36227-count-time (139 downloads)

_________________________
Toby Speight
030103016 (80GB Mk2a, blue)
030102806 (0GB Mk2a, blue)