summaryrefslogtreecommitdiff
path: root/plugins/ape/ape.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/ape/ape.c')
-rw-r--r--plugins/ape/ape.c259
1 files changed, 0 insertions, 259 deletions
diff --git a/plugins/ape/ape.c b/plugins/ape/ape.c
deleted file mode 100644
index 9443dfa2..00000000
--- a/plugins/ape/ape.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- apedec - Monkey's Audio Decoder plugin for DeaDBeeF player
- http://deadbeef.sourceforge.net
-
- Copyright (C) 2009 Alexey Yakovenko
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Note: DeaDBeeF player itself uses different license
-*/
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include "../../deadbeef.h"
-#include "apewrapper.h"
-
-#define min(x,y) ((x)<(y)?(x):(y))
-#define max(x,y) ((x)>(y)?(x):(y))
-
-static DB_decoder_t plugin;
-static DB_functions_t *deadbeef;
-
-static void *ape_dec;
-static int ape_blk_size;
-
-#define READBUF_SIZE 0x20000
-
-static char ape_readbuf[READBUF_SIZE];
-static int ape_blocks_left;
-static int ape_total_blocks;
-static float timestart;
-static float timeend;
-static int samplesdecoded;
-
-// precalc for bps conversion
-static int32_t mask;
-static float scaler;
-static int32_t neg;
-static int32_t sign;
-static int32_t signshift;
-
-static int
-ape_seek (float seconds);
-
-static int
-ape_init (DB_playItem_t *it) {
- ape_dec = ape_decompress_create (it->fname);
- if (!ape_dec) {
- printf ("ape_decompress_create failed for file %s\n", it->fname);
- return -1;
- }
- WAVEFORMATEX wfe;
- ape_decompress_get_info_data (ape_dec, APE_INFO_WAVEFORMATEX, &wfe);
- int size = ape_decompress_get_info_int (ape_dec, APE_INFO_WAV_HEADER_BYTES);
- char buf[size];
- ape_decompress_get_info_data_sized (ape_dec, APE_INFO_WAV_HEADER_DATA, buf, size);
- ape_blk_size = ape_decompress_get_info_int (ape_dec, APE_INFO_BLOCK_ALIGN);
- ape_total_blocks = ape_blocks_left = ape_decompress_get_info_int (ape_dec, APE_DECOMPRESS_TOTAL_BLOCKS);
- samplesdecoded = 0;
- plugin.info.bps = wfe.wBitsPerSample;
- plugin.info.samplerate = wfe.nSamplesPerSec;
- plugin.info.channels = wfe.nChannels;
- plugin.info.readpos = 0;
- if (it->timeend > 0) {
- timestart = it->timestart;
- timeend = it->timeend;
- ape_seek (0);
- }
- else {
- timestart = 0;
- timeend = it->duration;
- }
-
- mask = (1<<(plugin.info.bps-1))-1;
- scaler = 1.f / ((1<<(plugin.info.bps-1))-1);
- neg = 1<<plugin.info.bps;
- sign = (1<<31);
- signshift = plugin.info.bps-1;
- return 0;
-}
-
-static void
-ape_free (void) {
- if (ape_dec) {
- ape_decompress_destroy (ape_dec);
- ape_dec = NULL;
- }
-}
-
-static int
-ape_read_int16 (char *buffer, int size) {
- int initsize = size;
- int nblocks = size / plugin.info.channels / 2;
- nblocks = min (nblocks, ape_blocks_left);
- nblocks = ape_decompress_getdata (ape_dec, ape_readbuf, nblocks);
-
- uint8_t *in = ape_readbuf;
- for (int i = 0; i < nblocks*plugin.info.channels; i++) {
- // convert from bps to int32_t
- int32_t sample = 0;
- int shift = 0;
- while (shift < plugin.info.bps - 8) {
- sample |= (*in << shift);
- in++;
- shift += 8;
- }
- sample |= ((char)(*in)) << (plugin.info.bps - 8);
- in++;
-
- // now that's convertable to 16 bit
- *((int16_t*)buffer) = (int16_t)sample;
- buffer += 2;
- }
-
- ape_blocks_left -= nblocks;
- samplesdecoded += nblocks;
- plugin.info.readpos = samplesdecoded / (float)plugin.info.samplerate - timestart;
- if (plugin.info.readpos >= timeend) {
- return 0;
- }
- return nblocks * 2 * plugin.info.channels;
-}
-
-static int
-ape_read_float32 (char *buffer, int size) {
- int initsize = size;
- int nblocks = size / plugin.info.channels / sizeof (float);
- nblocks = min (nblocks, ape_blocks_left);
- nblocks = ape_decompress_getdata (ape_dec, ape_readbuf, nblocks);
-
- uint8_t *in = ape_readbuf;
- for (int i = 0; i < nblocks*plugin.info.channels; i++) {
- // convert from bps to int32_t
- int32_t sample = 0;
- int shift = 0;
- while (shift < plugin.info.bps - 8) {
- sample |= (*in << shift);
- in++;
- shift += 8;
- }
- sample |= ((char)(*in)) << (plugin.info.bps - 8);
- in++;
-
- // now that's convertable to float32
- *((float*)buffer) = (sample - ((sample&sign)>>signshift)*neg) * scaler;
- buffer += sizeof (float);
- }
-
- ape_blocks_left -= nblocks;
- samplesdecoded += nblocks;
- plugin.info.readpos = samplesdecoded / (float)plugin.info.samplerate - timestart;
- if (plugin.info.readpos >= timeend) {
- return 0;
- }
- return nblocks * sizeof (float) * plugin.info.channels;
-}
-
-static int
-ape_seek (float seconds) {
- seconds += timestart;
- int nblock = seconds * plugin.info.samplerate;
- ape_decompress_seek (ape_dec, nblock);
- samplesdecoded = nblock;
- ape_blocks_left = ape_total_blocks - nblock;
- plugin.info.readpos = samplesdecoded / (float)plugin.info.samplerate - timestart;
- return 0;
-}
-
-static DB_playItem_t *
-ape_insert (DB_playItem_t *after, const char *fname) {
- void *dec = ape_decompress_create (fname);
- if (!dec) {
- return NULL;
- }
- WAVEFORMATEX wfe;
- ape_decompress_get_info_data (dec, APE_INFO_WAVEFORMATEX, &wfe);
-
- float duration = ape_decompress_get_info_int (dec, APE_DECOMPRESS_TOTAL_BLOCKS) / (float)wfe.nSamplesPerSec;
- ape_decompress_destroy (dec);
- DB_playItem_t *it;
- it = deadbeef->pl_insert_cue (after, fname, &plugin, "APE", duration);
- if (it) {
- return it;
- }
-
- it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
- it->fname = strdup (fname);
- it->filetype = "APE";
- it->duration = duration;
-
- // try to read tags
- FILE *fp = fopen (fname, "rb");
- if (!fp) {
- deadbeef->pl_item_free (it);
- return NULL;
- }
-
- int v2err = deadbeef->junk_read_id3v2 (it, fp);
- int v1err = deadbeef->junk_read_id3v1 (it, fp);
- if (v1err >= 0) {
- fseek (fp, -128, SEEK_END);
- }
- else {
- fseek (fp, 0, SEEK_END);
- }
- int apeerr = deadbeef->junk_read_ape (it, fp);
- deadbeef->pl_add_meta (it, "title", NULL);
- fclose (fp);
-
- after = deadbeef->pl_insert_item (after, it);
-
- return after;
-}
-
-static const char * exts[] = { "ape", NULL };
-static const char *filetypes[] = { "APE", NULL };
-
-// define plugin interface
-static DB_decoder_t plugin = {
- DB_PLUGIN_SET_API_VERSION
- .plugin.version_major = 0,
- .plugin.version_minor = 1,
- .plugin.type = DB_PLUGIN_DECODER,
- .plugin.name = "Monkey's Audio decoder",
- .plugin.author = "Alexey Yakovenko",
- .plugin.email = "waker@users.sourceforge.net",
- .plugin.website = "http://deadbeef.sf.net",
- .init = ape_init,
- .free = ape_free,
- .read_int16 = ape_read_int16,
- .read_float32 = ape_read_float32,
- .seek = ape_seek,
- .insert = ape_insert,
- .exts = exts,
- .id = "stdape",
- .filetypes = filetypes
-};
-
-DB_plugin_t *
-ape_load (DB_functions_t *api) {
- deadbeef = api;
- return DB_PLUGIN (&plugin);
-}
-