appearantly this is working

This commit is contained in:
Nishi 2025-11-24 16:21:56 +09:00
commit e417ff18a0
Signed by: nishi
GPG key ID: 27EF69B208EB9343
5 changed files with 234 additions and 38 deletions

View file

@ -5,14 +5,16 @@
static void* audio;
pthread_mutex_t audio_mutex;
queue_t* queue = NULL;
queue_t* queue = NULL;
int queue_seek = -1;
int paused = 0;
static void handler(void* handle, void* user, void* data, int frames) {
memset(data, 0, frames * 2 * 2);
pthread_mutex_lock(&audio_mutex);
if(arrlen(queue) > 0) {
int from_frames = frames * queue[0].sfi.samplerate / MDEAudioRate;
if(queue_seek != -1 && !paused) {
int from_frames = frames * queue[queue_seek].sfi.samplerate / MDEAudioRate;
float* from = malloc(from_frames * sizeof(*from) * 2);
float* to = malloc(frames * sizeof(*to) * 2);
SRC_DATA d;
@ -22,18 +24,21 @@ static void handler(void* handle, void* user, void* data, int frames) {
d.data_out = to;
d.input_frames = from_frames;
d.output_frames = frames;
d.src_ratio = (double)MDEAudioRate / queue[0].sfi.samplerate;
d.src_ratio = (double)MDEAudioRate / queue[queue_seek].sfi.samplerate;
f = sf_readf_float(queue[0].sf, from, from_frames);
f = sf_readf_float(queue[queue_seek].sf, from, from_frames);
src_simple(&d, SRC_SINC_BEST_QUALITY, 2);
src_float_to_short_array(to, data, frames * 2);
queue[0].frames += f;
queue[queue_seek].frames += f;
free(from);
free(to);
if(f < from_frames) {
arrdel(queue, 0);
queue_seek++;
if(queue_seek >= arrlen(queue)) {
queue_seek = -1;
}
}
}
pthread_mutex_unlock(&audio_mutex);
@ -55,5 +60,8 @@ void audio_queue(const char* path) {
pthread_mutex_lock(&audio_mutex);
arrput(queue, q);
if(queue_seek == -1) queue_seek = arrlen(queue) - 1;
ui_set_play_queue(arrlen(queue));
pthread_mutex_unlock(&audio_mutex);
}

101
mauplay/id3.c Normal file
View file

@ -0,0 +1,101 @@
#include "mauplay.h"
static unsigned int syncsafe(FILE* f) {
unsigned char d[4];
unsigned int r = 0;
int i;
fread(d, 4, 1, f);
for(i = 0; i < 4; i++) {
r = r << 7;
r = r | (d[i] & 127);
}
return r;
}
static unsigned int big(FILE* f) {
unsigned char d[4];
unsigned int r = 0;
int i;
fread(d, 4, 1, f);
for(i = 0; i < 4; i++) {
r = r << 8;
r = r | d[i];
}
return r;
}
unsigned char* id3_findimage(const char* path, size_t* size) {
FILE* f = fopen(path, "rb");
unsigned char* d = NULL;
char sig[3];
unsigned char ver[2];
unsigned char flag;
unsigned char frame[4];
unsigned int dsz = 0;
if(f == NULL) return NULL;
fread(sig, 3, 1, f);
if(memcmp(sig, "ID3", 3) != 0) return NULL;
fread(ver, 2, 1, f);
if(memcmp(ver, "\x04\x00", 2) != 0 && memcmp(ver, "\x03\x00", 2) != 0) return NULL;
fread(&flag, 1, 1, f);
if(flag & (1 << 6)) return NULL; /* FIXME */
if(flag & (1 << 7)) return NULL; /* what even is this??? */
dsz = syncsafe(f);
while(dsz > 0) {
unsigned int fsz;
fread(frame, 4, 1, f);
if(frame[0] == 0) break; /* XXX: Is this ok? */
if(memcmp(ver, "\x04\x00", 2) == 0) {
fsz = syncsafe(f);
} else {
fsz = big(f);
}
fseek(f, 2, SEEK_CUR);
if(memcmp(frame, "APIC", 4) == 0) {
unsigned char* buffer = malloc(fsz);
int i;
fread(buffer, fsz, 1, f);
for(i = 1; i < fsz; i++) {
if(buffer[i] == 0) break;
}
i++;
/* XXX: 0 is technically Other - am not sure if this should be done... */
if(buffer[i] == 0 || buffer[i] == 3) {
int count = (buffer[0] == 1 || buffer[0] == 2) ? 2 : 1;
i++;
for(; i < fsz; i++) {
if(buffer[i] == 0) count--;
if(count == 0) break;
}
i++;
d = malloc(fsz - i);
memcpy(d, buffer + i, fsz - i);
*size = fsz - i;
}
free(buffer);
if(d != NULL) break;
} else {
fseek(f, fsz, SEEK_CUR);
}
dsz -= 4 + 4 + 2 + fsz;
}
fclose(f);
return d;
}

View file

@ -256,7 +256,6 @@ int main() {
db_scan();
audio_init();
audio_queue("test2.mp3");
MwLoop(window);
}

View file

@ -70,8 +70,13 @@ void ui_set_genres(int v);
/* audio.c */
extern pthread_mutex_t audio_mutex;
extern queue_t* queue;
extern int queue_seek;
extern int paused;
void audio_init(void);
void audio_queue(const char* path);
/* id3.c */
unsigned char* id3_findimage(const char* path, size_t* size);
#endif

View file

@ -8,6 +8,7 @@ static void* albums;
static void* artists;
static void* genres;
void* ui_last;
static int changed = 0;
void ui_list_reset(const char* merge) {
void* p;
@ -184,45 +185,56 @@ static void tree_activate(MwWidget handle, void* user, void* client) {
}
}
int queue_last = 0;
static void list_activate(MwWidget handle, void* user, void* client) {
if(ui_last == play_queue) {
pthread_mutex_lock(&audio_mutex);
queue_seek = (*(int*)client) - 1;
queue[queue_seek].frames = 0;
sf_seek(queue[queue_seek].sf, 0, SEEK_SET);
pthread_mutex_unlock(&audio_mutex);
} else if(ui_last == all_music) {
audio_queue(db_musics[(*(int*)client) - 1].key);
}
}
int queue_last = -1;
static void window_tick(MwWidget handle, void* user, void* client) {
pthread_mutex_lock(&audio_mutex);
if(queue_last != arrlen(queue)) {
if(queue_last != queue_seek && queue_seek != -1) {
int ind;
char* buf;
if(ui_last == play_queue) {
pthread_mutex_unlock(&audio_mutex);
MwDispatchUserHandler(tree, MwNactivateHandler, ui_last);
pthread_mutex_lock(&audio_mutex);
}
ui_set_play_queue(arrlen(queue));
ind = shgeti(db_musics, queue[queue_seek].path);
buf = malloc(strlen(db_musics[ind].title) + 1 + strlen(db_musics[ind].artist) + 1);
if(arrlen(queue) == 0) {
MwVaApply(info,
MwNtext, "",
NULL);
} else {
int ind = shgeti(db_musics, queue[0].path);
char* buf = malloc(strlen(db_musics[ind].title) + 1 + strlen(db_musics[ind].artist) + 1);
buf[0] = 0;
strcpy(buf, db_musics[ind].title);
strcat(buf, "\n");
strcat(buf, db_musics[ind].artist);
buf[0] = 0;
strcpy(buf, db_musics[ind].title);
strcat(buf, "\n");
strcat(buf, db_musics[ind].artist);
MwVaApply(info,
MwNtext, buf,
NULL);
MwVaApply(seekbar,
MwNmaxValue, queue[queue_seek].sfi.frames / queue[queue_seek].sfi.samplerate,
NULL);
MwVaApply(info,
MwNtext, buf,
NULL);
MwVaApply(seekbar,
MwNmaxValue, queue[0].sfi.frames / queue[0].sfi.samplerate,
NULL);
free(buf);
}
free(buf);
} else if(queue_seek == -1) {
MwVaApply(info,
MwNtext, "",
NULL);
}
if(arrlen(queue) > 0) {
int elsec = queue[0].frames / queue[0].sfi.samplerate;
int rmsec = (queue[0].sfi.frames / queue[0].sfi.samplerate) - elsec;
if(arrlen(queue) > 0 && queue_seek != -1) {
int elsec = queue[queue_seek].frames / queue[queue_seek].sfi.samplerate;
int rmsec = (queue[queue_seek].sfi.frames / queue[queue_seek].sfi.samplerate) - elsec;
char buf[64];
sprintf(buf, "%d:%02d", elsec / 60, elsec % 60);
@ -235,9 +247,14 @@ static void window_tick(MwWidget handle, void* user, void* client) {
MwNtext, buf,
NULL);
MwVaApply(seekbar,
MwNvalue, elsec,
NULL);
if(changed) {
sf_seek(queue[queue_seek].sf, (queue[queue_seek].frames = MwGetInteger(seekbar, MwNvalue) * queue[queue_seek].sfi.samplerate), SEEK_SET);
changed = 0;
} else {
MwVaApply(seekbar,
MwNvalue, elsec,
NULL);
}
} else {
MwVaApply(eltime,
MwNtext, "0:00",
@ -246,7 +263,65 @@ static void window_tick(MwWidget handle, void* user, void* client) {
MwNtext, "0:00",
NULL);
}
queue_last = arrlen(queue);
queue_last = queue_seek;
pthread_mutex_unlock(&audio_mutex);
}
static void seekbar_changed(MwWidget handle, void* user, void* client) {
changed = 1;
}
static void bskipback_activate(MwWidget handle, void* user, void* client) {
pthread_mutex_lock(&audio_mutex);
if(queue_seek == -1) {
queue_seek = 0;
} else {
if(queue_seek > 0) queue_seek--;
}
if(arrlen(queue) > 0) {
queue[queue_seek].frames = 0;
sf_seek(queue[queue_seek].sf, 0, SEEK_SET);
} else {
queue_seek = -1;
}
pthread_mutex_unlock(&audio_mutex);
}
static void bplay_activate(MwWidget handle, void* user, void* client) {
pthread_mutex_lock(&audio_mutex);
paused = 0;
pthread_mutex_unlock(&audio_mutex);
}
static void bpause_activate(MwWidget handle, void* user, void* client) {
pthread_mutex_lock(&audio_mutex);
paused = 1;
pthread_mutex_unlock(&audio_mutex);
}
static void bstop_activate(MwWidget handle, void* user, void* client) {
pthread_mutex_lock(&audio_mutex);
if(queue_seek != -1) {
queue[queue_seek].frames = 0;
sf_seek(queue[queue_seek].sf, 0, SEEK_SET);
}
queue_seek = -1;
pthread_mutex_unlock(&audio_mutex);
}
static void bskipfwd_activate(MwWidget handle, void* user, void* client) {
pthread_mutex_lock(&audio_mutex);
if(queue_seek == -1) {
queue_seek = 0;
} else {
if(queue_seek < (arrlen(queue) - 1)) queue_seek++;
}
if(arrlen(queue) > 0) {
queue[queue_seek].frames = 0;
sf_seek(queue[queue_seek].sf, 0, SEEK_SET);
} else {
queue_seek = -1;
}
pthread_mutex_unlock(&audio_mutex);
}
@ -261,6 +336,14 @@ void ui_init(void) {
ui_set_genres(0);
ui_last = all_music;
MwAddUserHandler(list, MwNactivateHandler, list_activate, NULL);
MwAddUserHandler(tree, MwNactivateHandler, tree_activate, NULL);
MwAddUserHandler(window, MwNtickHandler, window_tick, NULL);
MwAddUserHandler(seekbar, MwNchangedHandler, seekbar_changed, NULL);
MwAddUserHandler(bskipback, MwNactivateHandler, bskipback_activate, NULL);
MwAddUserHandler(bplay, MwNactivateHandler, bplay_activate, NULL);
MwAddUserHandler(bpause, MwNactivateHandler, bpause_activate, NULL);
MwAddUserHandler(bstop, MwNactivateHandler, bstop_activate, NULL);
MwAddUserHandler(bskipfwd, MwNactivateHandler, bskipfwd_activate, NULL);
}