123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "kill.h"
- #include "exit_status.h"
- #define strdup _strdup
- /* Up to 128 songs, for now */
- static char *songs[128];
- static int should_shuffle = 0;
- static int song_count = 0;
- static char read_buf[1024];
- static void callback_playlist() {
- for (size_t i = 0; i < 128; ++i) {
- if (songs[i]) free(songs[i]);
- }
- }
- void playlist_init() {
- for (size_t i = 0; i < 128; ++i) songs[i] = NULL;
- kill_push(callback_playlist);
- }
- void playlist_load(const char *path) {
- FILE *f = fopen(path, "r");
- if (!f) {
- printf("Could not open playlist '%s'\n", path);
- kill(EX_ERR_BAD_PLAYLIST);
- }
- int write = 0;
- int song_write = 0;
- for (;;) {
- int c = fgetc(f);
- if (c == EOF) break;
- if (c == '\n') {
- if (read_buf[0] == '+') {
- read_buf[write] = '\0';
- if (!strcmp(read_buf, "+shuffle")) {
- should_shuffle = 1;
- }
- }
- else {
- read_buf[write] = '\0';
- songs[song_write++] = strdup(read_buf);
- if (song_write >= 128) break;
- }
- write = 0;
- }
- else read_buf[write++] = (char)c;
- if (write >= 1024) {
- break;
- }
- }
- fclose(f);
- song_count = song_write;
- if (song_count == 0) {
- printf("Playlist '%s' contains no songs!", path);
- kill(EX_ERR_NO_SONGS);
- }
- }
- static const char *next_normal() {
- static int index = 0;
- char *result = songs[index];
- index = (index + 1) % song_count;
- return result;
- }
- static const char *next_shuffle() {
- static int has_played[128] = { 0 };
-
- size_t choices[128];
- size_t choice_count = 0;
- for (size_t i = 0; i < song_count; ++i) {
- if (!has_played[i]) {
- choices[choice_count++] = i;
- }
- }
- if (choice_count == 0) {
- for (size_t i = 0; i < song_count; ++i) {
- has_played[i] = 0;
- choices[i] = i;
- }
- choice_count = song_count;
- }
- size_t index = ((rand() / (float)RAND_MAX) * (choice_count - 1));
- char *result = songs[choices[index]];
- has_played[choices[index]] = 1;
- return result;
- }
- const char *playlist_next() {
- if (should_shuffle) return next_shuffle();
- return next_normal();
- }
|