A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 100 lines 2.9 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * 9 * Copyright (C) 2013 Marcin Bukat 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 2 14 * of the License, or (at your option) any later version. 15 * 16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 17 * KIND, either express or implied. 18 * 19 ****************************************************************************/ 20 21#include "plugin.h" 22#include <tlsf.h> 23#include "lua.h" 24static const unsigned int sentinel = 0xBA5EFAC7; 25#define SENTINEL(n) (sentinel ^ (n)) 26 27static char *pluginbuf_ptr = NULL; 28static size_t pluginbuf_size = 0; 29static char *audiobuf_ptr = NULL; 30static size_t audiobuf_size = 0; 31 32static void set_sentinel(void* buf, size_t size) 33{ 34 size_t i; 35 unsigned int *b = (int*) buf; 36 for(i = 0; i < size / sizeof(sentinel); i++) 37 *b++ = SENTINEL(i); 38} 39 40static size_t check_sentinel(void* buf, size_t size) 41{ 42 const size_t sz = size / sizeof(sentinel); 43 size_t unused = 0; 44 size_t i; 45 unsigned int *b = (int*) buf; 46 for(i = 0; i < sz; i++) 47 if (b[i] == SENTINEL(i)) 48 { 49 unused++; 50 while(++i < sz && b[i] == SENTINEL(i) && ++unused) 51 {;;} 52 } 53 return unused * sizeof(sentinel); 54} 55 56size_t rock_get_allocated_bytes(void) 57{ 58 return pluginbuf_size + audiobuf_size; 59} 60 61size_t rock_get_unused_bytes(void) 62{ 63 size_t unused = 0; 64 if (pluginbuf_size) 65 unused += check_sentinel(pluginbuf_ptr, pluginbuf_size); 66 if (audiobuf_size) 67 unused += check_sentinel(audiobuf_ptr, audiobuf_size); 68 return unused; 69} 70 71void *get_new_area(size_t *size) 72{ 73 if (pluginbuf_ptr == NULL) 74 { 75 pluginbuf_ptr = rb->plugin_get_buffer(size); 76 77 pluginbuf_size = *size; 78 set_sentinel(pluginbuf_ptr, pluginbuf_size); 79 80 /* kill tlsf signature if any */ 81 memset(pluginbuf_ptr, 0, 4); 82 83 return pluginbuf_ptr; 84 } 85 86 /* only grab the next area if lua already tried + failed to garbage collect*/ 87 if (audiobuf_ptr == NULL && (get_lua_OOM())->count > 0) 88 { 89 /* grab audiobuffer */ 90 audiobuf_ptr = rb->plugin_get_audio_buffer(size); 91 92 audiobuf_size = *size; 93 set_sentinel(audiobuf_ptr, audiobuf_size); 94 95 return audiobuf_ptr; 96 } 97 98 *size = 0; 99 return ((void *) ~0u); 100}