Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2005 David Bryant |
| 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame] | 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version 2 |
| 15 | * of the License, or (at your option) any later version. |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 16 | * |
| 17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 18 | * KIND, either express or implied. |
| 19 | * |
| 20 | ****************************************************************************/ |
| 21 | |
Thom Johansen | c91e0bb | 2005-10-13 11:32:52 +0000 | [diff] [blame] | 22 | #include "codeclib.h" |
| 23 | #include "libwavpack/wavpack.h" |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 24 | |
Jens Arnold | b8749fd | 2006-01-18 00:05:14 +0000 | [diff] [blame] | 25 | CODEC_HEADER |
| 26 | |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 27 | #define BUFFER_SIZE 4096 |
| 28 | |
Dave Bryant | 0ad19c7 | 2006-03-26 22:54:15 +0000 | [diff] [blame] | 29 | static int32_t temp_buffer [BUFFER_SIZE] IBSS_ATTR; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 30 | |
Dave Bryant | 0ad19c7 | 2006-03-26 22:54:15 +0000 | [diff] [blame] | 31 | static int32_t read_callback (void *buffer, int32_t bytes) |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 32 | { |
Dave Bryant | 0ad19c7 | 2006-03-26 22:54:15 +0000 | [diff] [blame] | 33 | int32_t retval = ci->read_filebuf (buffer, bytes); |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 34 | ci->set_offset(ci->curpos); |
Dave Bryant | 1983738 | 2005-06-30 06:09:59 +0000 | [diff] [blame] | 35 | return retval; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 36 | } |
| 37 | |
Daniel Stenberg | 1dd672f | 2005-06-22 19:41:30 +0000 | [diff] [blame] | 38 | /* this is the codec entry point */ |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 39 | enum codec_status codec_main(enum codec_entry_call_reason reason) |
| 40 | { |
| 41 | if (reason == CODEC_LOAD) { |
| 42 | /* Generic codec initialisation */ |
| 43 | ci->configure(DSP_SET_SAMPLE_DEPTH, 28); |
| 44 | } |
| 45 | |
| 46 | return CODEC_OK; |
| 47 | } |
| 48 | |
| 49 | /* this is called for each file to process */ |
| 50 | enum codec_status codec_run(void) |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 51 | { |
| 52 | WavpackContext *wpc; |
| 53 | char error [80]; |
Dave Bryant | 24d6535 | 2005-06-27 00:12:40 +0000 | [diff] [blame] | 54 | int bps, nchans, sr_100; |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 55 | intptr_t param; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 56 | |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 57 | if (codec_init()) |
| 58 | return CODEC_ERROR; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 59 | |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 60 | ci->seek_buffer (ci->id3->offset); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 61 | |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 62 | /* Create a decoder instance */ |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 63 | wpc = WavpackOpenFileInput (read_callback, error); |
| 64 | |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 65 | if (!wpc) |
| 66 | return CODEC_ERROR; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 67 | |
Dave Bryant | bcf97a4 | 2007-08-12 06:36:06 +0000 | [diff] [blame] | 68 | ci->configure(DSP_SWITCH_FREQUENCY, WavpackGetSampleRate (wpc)); |
| 69 | codec_set_replaygain(ci->id3); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 70 | bps = WavpackGetBytesPerSample (wpc); |
| 71 | nchans = WavpackGetReducedChannels (wpc); |
Michael Sevakis | 97f369a | 2007-02-10 16:34:16 +0000 | [diff] [blame] | 72 | ci->configure(DSP_SET_STEREO_MODE, nchans == 2 ? STEREO_INTERLEAVED : STEREO_MONO); |
Dave Bryant | 24d6535 | 2005-06-27 00:12:40 +0000 | [diff] [blame] | 73 | sr_100 = ci->id3->frequency / 100; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 74 | |
| 75 | ci->set_elapsed (0); |
| 76 | |
| 77 | /* The main decoder loop */ |
| 78 | |
| 79 | while (1) { |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 80 | int32_t nsamples; |
| 81 | enum codec_command_action action = ci->get_command(¶m); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 82 | |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 83 | if (action == CODEC_ACTION_HALT) |
| 84 | break; |
| 85 | |
| 86 | if (action == CODEC_ACTION_SEEK_TIME) { |
Dave Bryant | 24d6535 | 2005-06-27 00:12:40 +0000 | [diff] [blame] | 87 | int curpos_ms = WavpackGetSampleIndex (wpc) / sr_100 * 10; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 88 | int n, d, skip; |
| 89 | |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 90 | if (param > curpos_ms) { |
| 91 | n = param - curpos_ms; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 92 | d = ci->id3->length - curpos_ms; |
Dave Bryant | 0ad19c7 | 2006-03-26 22:54:15 +0000 | [diff] [blame] | 93 | skip = (int)((int64_t)(ci->filesize - ci->curpos) * n / d); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 94 | ci->seek_buffer (ci->curpos + skip); |
| 95 | } |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 96 | else if (curpos_ms != 0) { |
| 97 | n = curpos_ms - param; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 98 | d = curpos_ms; |
Dave Bryant | 0ad19c7 | 2006-03-26 22:54:15 +0000 | [diff] [blame] | 99 | skip = (int)((int64_t) ci->curpos * n / d); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 100 | ci->seek_buffer (ci->curpos - skip); |
| 101 | } |
| 102 | |
| 103 | wpc = WavpackOpenFileInput (read_callback, error); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 104 | if (!wpc) |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 105 | { |
| 106 | ci->seek_complete(); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 107 | break; |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 108 | } |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 109 | |
Dave Bryant | 24d6535 | 2005-06-27 00:12:40 +0000 | [diff] [blame] | 110 | ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 111 | ci->seek_complete(); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 112 | } |
| 113 | |
Dave Bryant | ff40af4 | 2006-02-06 07:40:35 +0000 | [diff] [blame] | 114 | nsamples = WavpackUnpackSamples (wpc, temp_buffer, BUFFER_SIZE / nchans); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 115 | |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 116 | if (!nsamples) |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 117 | break; |
| 118 | |
Michael Sevakis | aba6ca0 | 2007-02-07 00:51:50 +0000 | [diff] [blame] | 119 | ci->pcmbuf_insert (temp_buffer, NULL, nsamples); |
Dave Bryant | 24d6535 | 2005-06-27 00:12:40 +0000 | [diff] [blame] | 120 | ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 121 | } |
| 122 | |
Michael Sevakis | c537d59 | 2011-04-27 03:08:23 +0000 | [diff] [blame^] | 123 | return CODEC_OK; |
Dave Bryant | 7dad7d3 | 2005-06-13 06:15:05 +0000 | [diff] [blame] | 124 | } |