diff -Naur _009/apps/SOURCES _010/apps/SOURCES --- _009/apps/SOURCES 2008-09-10 21:48:21.801129600 +0900 +++ _010/apps/SOURCES 2008-09-10 21:59:58.000000000 +0900 @@ -204,3 +204,4 @@ #elif CONFIG_KEYPAD == IAUDIO67_PAD keymaps/keymap-iaudio67.c #endif +tdspeed.c diff -Naur _009/apps/dsp.c _010/apps/dsp.c --- _009/apps/dsp.c 2008-09-10 21:48:21.871230400 +0900 +++ _010/apps/dsp.c 2008-09-11 02:59:50.353948800 +0900 @@ -32,6 +32,7 @@ #include "replaygain.h" #include "misc.h" #include "debug.h" +#include "tdspeed.h" /* 16-bit samples are scaled based on these constants. The shift should be * no more than 15. @@ -41,8 +42,14 @@ #define NATIVE_DEPTH 16 /* If the buffer sizes change, check the assembly code! */ -#define SAMPLE_BUF_COUNT 256 -#define RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ +#define SMALL_SAMPLE_BUF_COUNT 256 +#define SMALL_RESAMPLE_BUF_COUNT (256 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ +#define BIG_SAMPLE_BUF_COUNT 4096 +#define BIG_RESAMPLE_BUF_COUNT (4096 * 4) /* Enough for 11,025 Hz -> 44,100 Hz*/ +int sample_buf_count; +int resample_buf_count; +#define SAMPLE_BUF_COUNT sample_buf_count +#define RESAMPLE_BUF_COUNT resample_buf_count #define DEFAULT_GAIN 0x01000000 #define SAMPLE_BUF_LEFT_CHANNEL 0 #define SAMPLE_BUF_RIGHT_CHANNEL (SAMPLE_BUF_COUNT/2) @@ -163,6 +170,8 @@ int sample_depth; int sample_bytes; int stereo_mode; + bool tdspeed_active; + int tdspeed_factor; /* % */ int frac_bits; #ifdef HAVE_SW_TONE_CONTROLS /* Filter struct for software bass/treble controls */ @@ -226,8 +235,12 @@ * of copying needed is minimized for that case. */ -int32_t sample_buf[SAMPLE_BUF_COUNT] IBSS_ATTR; -static int32_t resample_buf[RESAMPLE_BUF_COUNT] IBSS_ATTR; +int32_t small_sample_buf[SMALL_SAMPLE_BUF_COUNT] IBSS_ATTR; +static int32_t small_resample_buf[SMALL_RESAMPLE_BUF_COUNT] IBSS_ATTR; +int32_t big_sample_buf[BIG_SAMPLE_BUF_COUNT]; +static int32_t big_resample_buf[BIG_RESAMPLE_BUF_COUNT]; +int32_t *sample_buf; +static int32_t *resample_buf; #if 0 /* Clip sample to arbitrary limits where range > 0 and min + range = max */ @@ -264,6 +277,38 @@ audio_dsp.codec_frequency); } +void tdspeed_setup(struct dsp_config *dspc) +{ + if(dspc == &dsp_conf[CODEC_IDX_AUDIO]) { +#if 0 + mylog("tdspeed_setup: CODEC_IDX_AUDIO, factor %d, %d, %d\n", + dspc->tdspeed_factor, dspc->codec_frequency, + dspc->stereo_mode != STEREO_MONO); +#endif + +dsp_set_eq(global_settings.eq_enabled); +dsp_set_crossfeed(global_settings.crossfeed); +if (global_settings.eq_enabled == true || global_settings.crossfeed == true) +{dspc->tdspeed_active = false;} +else +{ + if(dspc->tdspeed_factor == 0 || dspc->tdspeed_factor == 100) + dspc->tdspeed_active = false; + else dspc->tdspeed_active + = tdspeed_init(dspc->codec_frequency == 0 ? NATIVE_FREQUENCY + : dspc->codec_frequency, + dspc->stereo_mode != STEREO_MONO, + dspc->tdspeed_factor); +} + } +} + +void dsp_set_speed(int percent) +{ + dsp_conf[CODEC_IDX_AUDIO].tdspeed_factor = percent; + tdspeed_setup(&dsp_conf[CODEC_IDX_AUDIO]); +} + /* Convert count samples to the internal format, if needed. Updates src * to point past the samples "consumed" and dst is set to point to the * samples to consume. Note that for mono, dst[0] equals dst[1], as there @@ -1156,6 +1201,9 @@ dsp->input_samples(samples, src, tmp); + if(dsp->tdspeed_active) + samples = tdspeed_doit(tmp, samples); + if (dsp->apply_gain) dsp->apply_gain(samples, &dsp->data, tmp); @@ -1207,6 +1255,19 @@ /* dsp_input_size MUST be called afterwards */ int dsp_output_count(struct dsp_config *dsp, int count) { + if(!dsp->tdspeed_active) { + sample_buf = small_sample_buf; + resample_buf = small_resample_buf; + sample_buf_count = SMALL_SAMPLE_BUF_COUNT; + resample_buf_count = SMALL_RESAMPLE_BUF_COUNT; + } else { + sample_buf = big_sample_buf; + resample_buf = big_resample_buf; + sample_buf_count = BIG_SAMPLE_BUF_COUNT; + resample_buf_count = BIG_RESAMPLE_BUF_COUNT; + } + if(dsp->tdspeed_active) + count = tdspeed_est_output_size(count); if (dsp->resample) { count = (int)(((unsigned long)count * NATIVE_FREQUENCY @@ -1240,6 +1301,9 @@ dsp->data.resample_data.delta) >> 16); } + if(dsp->tdspeed_active) + count = tdspeed_est_input_size(count); + return count; } @@ -1287,6 +1351,7 @@ dsp->frequency = dsp->codec_frequency; resampler_new_delta(dsp); + tdspeed_setup(dsp); break; case DSP_SET_SAMPLE_DEPTH: @@ -1316,6 +1381,7 @@ dsp->stereo_mode = value; dsp->data.num_channels = value == STEREO_MONO ? 1 : 2; dsp_update_functions(dsp); + tdspeed_setup(dsp); break; case DSP_RESET: @@ -1340,6 +1406,7 @@ dsp_update_functions(dsp); resampler_new_delta(dsp); + tdspeed_setup(dsp); break; case DSP_FLUSH: @@ -1347,6 +1414,7 @@ sizeof (dsp->data.resample_data)); resampler_new_delta(dsp); dither_init(dsp); + tdspeed_setup(dsp); break; case DSP_SET_TRACK_GAIN: diff -Naur _009/apps/dsp.h _010/apps/dsp.h --- _009/apps/dsp.h 2008-09-10 06:57:28.000000000 +0900 +++ _010/apps/dsp.h 2008-09-10 21:59:09.292176000 +0900 @@ -165,5 +165,6 @@ int sound_get_pitch(void); int dsp_callback(int msg, intptr_t param); void dsp_dither_enable(bool enable); +void dsp_set_speed(int speed); #endif diff -Naur _009/apps/lang/english.lang _010/apps/lang/english.lang --- _009/apps/lang/english.lang 2008-09-10 21:48:22.051489600 +0900 +++ _010/apps/lang/english.lang 2008-09-10 22:38:53.520528000 +0900 @@ -12400,3 +12400,17 @@ *: "Long Button Press Duration" + + id: LANG_SPEED + desc: time-domain speed compress/stretch + user: + + *: "Playback Speed" + + + *: "Playback Speed" + + + *: "Playback Speed" + + diff -Naur _009/apps/menus/eq_menu.c _010/apps/menus/eq_menu.c --- _009/apps/menus/eq_menu.c 2008-09-10 21:48:22.231748800 +0900 +++ _010/apps/menus/eq_menu.c 2008-09-11 01:05:35.246788800 +0900 @@ -72,6 +72,10 @@ { int i; dsp_set_eq(global_settings.eq_enabled); + + if (global_settings.eq_enabled==true) + global_settings.sound_speed=100; + dsp_set_eq_precut(global_settings.eq_precut); /* Update all bands */ for(i = 0; i < 24; i++) { diff -Naur _009/apps/menus/sound_menu.c _010/apps/menus/sound_menu.c --- _009/apps/menus/sound_menu.c 2008-09-10 06:57:29.000000000 +0900 +++ _010/apps/menus/sound_menu.c 2008-09-11 02:59:30.755768000 +0900 @@ -72,9 +72,22 @@ #endif ); +static int sound_opt_callback(int action, const struct menu_item_ex *this_item) +{ + switch (action) + { + case ACTION_EXIT_MENUITEM: + if (global_settings.crossfeed == true) + global_settings.sound_speed=100; + action = lowlatency_callback(action, this_item); + break; + } + return action; +} + #if CONFIG_CODEC == SWCODEC /* Crossfeed Submenu */ - MENUITEM_SETTING(crossfeed, &global_settings.crossfeed, lowlatency_callback); + MENUITEM_SETTING(crossfeed, &global_settings.crossfeed, sound_opt_callback); MENUITEM_SETTING(crossfeed_direct_gain, &global_settings.crossfeed_direct_gain, lowlatency_callback); MENUITEM_SETTING(crossfeed_cross_gain, @@ -116,7 +129,7 @@ #endif &balance,&channel_config,&stereo_width #if CONFIG_CODEC == SWCODEC - ,&crossfeed_menu, &equalizer_menu, &dithering_enabled + ,&crossfeed_menu, &equalizer_menu, &dithering_enabled #endif #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) ,&loudness,&avc,&superbass,&mdb_enable,&mdb_strength diff -Naur _009/apps/onplay.c _010/apps/onplay.c --- _009/apps/onplay.c 2008-09-10 21:48:24.000000000 +0900 +++ _010/apps/onplay.c 2008-09-11 02:59:11.578192000 +0900 @@ -56,6 +56,9 @@ #ifdef HAVE_LCD_BITMAP #include "icons.h" #endif +#if CONFIG_CODEC == SWCODEC +#include "menus/eq_menu.h" +#endif #include "sound_menu.h" #include "filetree.h" #include "playlist_menu.h" @@ -1053,6 +1056,24 @@ pitch_screen, NULL, NULL, Icon_Audio); #endif +static int sound_speed_callback(int action, const struct menu_item_ex *this_item) +{ + switch (action) + { + case ACTION_EXIT_MENUITEM: + dsp_set_eq(global_settings.eq_enabled); + dsp_set_crossfeed(global_settings.crossfeed); + if (!(global_settings.sound_speed==0||global_settings.sound_speed==100)) + {global_settings.eq_enabled=false; + global_settings.crossfeed=false;}; + action = lowlatency_callback(action, this_item); + break; + } + return action; +} +MENUITEM_SETTING(sound_speed, &global_settings.sound_speed, + sound_speed_callback); + /* CONTEXT_[TREE|ID3DB] items */ static int clipboard_callback(int action,const struct menu_item_ex *this_item); MENUITEM_FUNCTION(rename_file_item, 0, ID2P(LANG_RENAME), @@ -1227,6 +1248,7 @@ #ifdef HAVE_PITCHSCREEN &pitch_screen_item, #endif + &sound_speed, ); /* used when onplay() is not called in the CONTEXT_WPS context */ MAKE_ONPLAYMENU( tree_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE), diff -Naur _009/apps/plugins/pictureflow.c _010/apps/plugins/pictureflow.c --- _009/apps/plugins/pictureflow.c 2008-09-10 22:50:16.512622400 +0900 +++ _010/apps/plugins/pictureflow.c 2008-09-10 22:16:13.394763200 +0900 @@ -917,6 +917,7 @@ /* resize image */ output_bmp.width = config.avg_album_width; output_bmp.height = config.avg_album_width; +// smooth_resize_bitmap(input_bmp, &output_bmp); rb->resize_bitmap(input_bmp, &output_bmp); /* Resized bitmap is now in the output buffer, diff -Naur _009/apps/settings.c _010/apps/settings.c --- _009/apps/settings.c 2008-09-10 21:48:22.682396800 +0900 +++ _010/apps/settings.c 2008-09-10 21:59:22.000000000 +0900 @@ -972,6 +972,7 @@ } dsp_dither_enable(global_settings.dithering_enabled); + dsp_set_speed(global_settings.sound_speed); #endif #ifdef HAVE_SPDIF_POWER diff -Naur _009/apps/settings.h _010/apps/settings.h --- _009/apps/settings.h 2008-09-10 21:48:22.702425600 +0900 +++ _010/apps/settings.h 2008-09-10 21:59:24.000000000 +0900 @@ -755,6 +755,7 @@ int eq_band23_gain; /* +/- dB */ bool dithering_enabled; + int sound_speed; #endif diff -Naur _009/apps/settings_list.c _010/apps/settings_list.c --- _009/apps/settings_list.c 2008-09-10 21:48:22.732468800 +0900 +++ _010/apps/settings_list.c 2008-09-10 21:59:32.000000000 +0900 @@ -1346,6 +1346,9 @@ /* dithering */ OFFON_SETTING(F_SOUNDSETTING, dithering_enabled, LANG_DITHERING, false, "dithering enabled", dsp_dither_enable), + INT_SETTING(0, sound_speed, LANG_SPEED, 100, "speed", + UNIT_INT, 35, 250, 5, + NULL, NULL, dsp_set_speed), #endif #ifdef HAVE_WM8758 SOUND_SETTING(F_NO_WRAP, bass_cutoff, LANG_BASS_CUTOFF, diff -Naur _009/apps/tdspeed.c _010/apps/tdspeed.c --- _009/apps/tdspeed.c 1970-01-01 09:00:00.000000000 +0900 +++ _010/apps/tdspeed.c 2008-09-10 21:20:20.213124800 +0900 @@ -0,0 +1,334 @@ +/* + * Audio time domain speed scaling / time compression/stretch. + * + * Copyright (C) 2006 by Nicolas Pitre + * + * Modified by Stéphane Doyon to adapt to Rockbox + * Copyright (C) 2006-2007 by Stéphane Doyon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include "system.h" +#include "tdspeed.h" + +#define mylog(...) +#define assert(...) + +#if 0 +#define assert(cond) \ + if(!(cond)) { \ + badlog("Assertion failed in %s at line %d: %s\n", \ + __FUNCTION__, __LINE__, #cond); \ + } +#endif + +#define MIN_RATE 8000 +#define MAX_RATE 48000 /* double buffer for double rate */ +#define MIN_FACTOR 35 +#define MAX_FACTOR 250 + +//#define FIXED_BUFSIZE 3072 /* 48KHz factor 3.0 */ +#define FIXED_BUFSIZE 3524 /* worse seen, not sure how to calc */ + +struct tdspeed_state_s { + bool stereo; + int shift_max; /* maximum displacement on a frame */ + int src_step; /* source window pace */ + int dst_step; /* destination window pace */ + int dst_order; /* power of two for dst_step */ + int ovl_shift; /* overlap buffer frame shift */ + int ovl_size; /* overlap buffer used size */ + int ovl_space; /* overlap buffer size */ + int32_t *ovl_buff[2]; /* overlap buffer */ +}; +static struct tdspeed_state_s tdspeed_state; + +static int32_t overlap_buffer[2][FIXED_BUFSIZE]; +static int32_t outbuf[2][TDSPEED_OUTBUFSIZE]; + +bool tdspeed_init(int samplerate, bool stereo, int factor) +{ + struct tdspeed_state_s *st = &tdspeed_state; + int src_frame_sz; + + if(factor == 100) + return false; + if (samplerate < MIN_RATE || samplerate > MAX_RATE) + return false; + if(factor MAX_FACTOR) + return false; + + st->stereo = !!stereo; + +#define MINFREQ 100 + st->dst_step = samplerate / MINFREQ; + + if (factor > 100) + st->dst_step = st->dst_step *100 /factor; + st->dst_order = 1; + + while (st->dst_step >>= 1) + st->dst_order++; + st->dst_step = (1 << st->dst_order); + st->src_step = st->dst_step * factor /100; + st->shift_max = (st->dst_step > st->src_step) ? st->dst_step : st->src_step; + + src_frame_sz = st->shift_max + st->dst_step; + if (st->dst_step > st->src_step) + src_frame_sz += st->dst_step - st->src_step; + st->ovl_space = ((src_frame_sz - 2)/st->src_step) * st->src_step + + src_frame_sz; + if (st->src_step > st->dst_step) + st->ovl_space += 2*st->src_step - st->dst_step; + + mylog( + "shift_max %d, src_step %d, dst_step %d, dst_order %d, src_frame_sz %d, ovl_space %d\n", + st->shift_max, st->src_step, st->dst_step, st->dst_order, src_frame_sz, st->ovl_space); + + assert(st->ovl_space <= FIXED_BUFSIZE); + + st->ovl_size = 0; + st->ovl_shift = 0; + + st->ovl_buff[0] = overlap_buffer[0]; + if(stereo) + st->ovl_buff[1] = overlap_buffer[1]; + else st->ovl_buff[1] = st->ovl_buff[0]; + + return true; +} + +int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2], int data_len, + int last, int out_size) +/* data_len in samples */ +{ + struct tdspeed_state_s *st = &tdspeed_state; + int32_t *curr, *prev, *dest[2], *d; + int i, j, next_frame, prev_frame, shift, src_frame_sz; + bool stereo = buf_in[0] != buf_in[1]; + assert(stereo == st->stereo); + + src_frame_sz = st->shift_max + st->dst_step; + if (st->dst_step > st->src_step) + src_frame_sz += st->dst_step - st->src_step; + + /* deal with overlap data first, if any */ + if (st->ovl_size) { + int have, copy, steps; + have = st->ovl_size; + if (st->ovl_shift > 0) + have -= st->ovl_shift; + /* append just enough data to have all of the overlap buffer consumed*/ + steps = (have - 1) / st->src_step; + copy = steps * st->src_step + src_frame_sz - have; + if (copy < src_frame_sz - st->dst_step) + copy += st->src_step; /* one more step to allow for pregap data */ + if (copy > data_len) copy = data_len; + assert(st->ovl_size +copy <= FIXED_BUFSIZE); + memcpy(st->ovl_buff[0] + st->ovl_size, buf_in[0], + copy * sizeof(int32_t)); + if(stereo) + memcpy(st->ovl_buff[1] + st->ovl_size, buf_in[1], + copy * sizeof(int32_t)); + if (!last && have + copy < src_frame_sz) { + /* still not enough to process at least one frame */ + st->ovl_size += copy; + return 0; + } + /* recursively call ourselves to process the overlap buffer */ + have = st->ovl_size; + st->ovl_size = 0; + if (copy == data_len) { + assert( (have+copy) <= FIXED_BUFSIZE); + return tdspeed_apply(buf_out, st->ovl_buff, have+copy, last, + out_size); + } + assert( (have+copy) <= FIXED_BUFSIZE); + i = tdspeed_apply(buf_out, st->ovl_buff, have+copy, -1, out_size); + dest[0] = buf_out[0] + i; + dest[1] = buf_out[1] + i; + /* readjust pointers to account for data already consumed */ + next_frame = copy - src_frame_sz + st->src_step; + prev_frame = next_frame - st->ovl_shift; + } else { + dest[0] = buf_out[0]; + dest[1] = buf_out[1]; + next_frame = prev_frame = 0; + if (st->ovl_shift > 0) + next_frame += st->ovl_shift; + else + prev_frame += -st->ovl_shift; + } + st->ovl_shift = 0; + + /* process all complete frames */ + while (data_len -next_frame >= src_frame_sz) { + /* find frame overlap by autocorelation */ + long long min_delta = ~(1ll << 63); /* most positive */ + shift = 0; +#define INC1 8 +#define INC2 32 + /* Power of 2 of a 28bit number requires 56bits, can accumulate + 256times in a 64bit variable. */ + assert(st->dst_step /INC2 <= 256); + assert(next_frame+st->shift_max-1 +st->dst_step-1 < data_len); + assert(prev_frame +st->dst_step-1 < data_len); + for (i = 0; i < st->shift_max; i += INC1) { + long long delta = 0; + curr = buf_in[0] +next_frame + i; + prev = buf_in[0] +prev_frame; + for (j = 0; j < st->dst_step; + j += INC2, curr += INC2, prev += INC2) { + int32_t diff = *curr - *prev; + delta += (long long)diff * diff; + if (delta >= min_delta) + goto skip; + } + if(stereo) { + curr = buf_in[1] +next_frame + i; + prev = buf_in[1] +prev_frame; + for (j = 0; j < st->dst_step; + j += INC2, curr += INC2, prev += INC2) { + int32_t diff = *curr - *prev; + delta += (long long)diff * diff; + if (delta >= min_delta) + goto skip; + } + } + min_delta = delta; + shift = i; + skip:; + } + + /* overlap fading-out previous frame with fading-in current frame */ + curr = buf_in[0] +next_frame + shift; + prev = buf_in[0] +prev_frame; + d = dest[0]; + assert(next_frame+shift +st->dst_step-1 < data_len); + assert(prev_frame +st->dst_step-1 < data_len); + assert(dest[0]-buf_out[0] +st->dst_step-1 < out_size); + for (i = 0, j = st->dst_step; j; i++, j--) { + *d++ = (*curr++ * (long long)i + + *prev++ * (long long)j) >> st->dst_order; + } + dest[0] = d; + if(stereo) { + curr = buf_in[1] +next_frame + shift; + prev = buf_in[1] +prev_frame; + d = dest[1]; + for (i = 0, j = st->dst_step; j; i++, j--) { + assert(d < buf_out[1] +out_size); + *d++ = (*curr++ * (long long)i + + *prev++ * (long long)j) >> st->dst_order; + } + dest[1] = d; + } + + /* adjust pointers for next frame */ + prev_frame = next_frame + shift + st->dst_step; + //assert(prev_frame == curr[0] -buf_in[0]); + next_frame += st->src_step; + /* here next_frame - prev_frame = src_step - dst_step - shift */ + assert(next_frame - prev_frame == st->src_step - st->dst_step - shift); + } + + /* now deal with remaining partial frames */ + if (last == -1) { + /* special overlap buffer processing: remember frame shift only */ + st->ovl_shift = next_frame - prev_frame; + } else if (last != 0) { + /* last call: purge all remaining data to output buffer */ + i = data_len -prev_frame; + assert(dest[0] +i <= buf_out[0] +out_size); + memcpy(dest[0], buf_in[0] +prev_frame, i * sizeof(int32_t)); + dest[0] += i; + if(stereo) { + assert(dest[1] +i <= buf_out[1] +out_size); + memcpy(dest[1], buf_in[1] +prev_frame, i * sizeof(int32_t)); + dest[1] += i; + } + } else { + /* preserve remaining data + needed overlap data for next call */ + st->ovl_shift = next_frame - prev_frame; + i = (st->ovl_shift < 0) ? next_frame : prev_frame; + st->ovl_size = data_len - i; + assert(st->ovl_size <= FIXED_BUFSIZE); + memcpy(st->ovl_buff[0], buf_in[0]+i, st->ovl_size * sizeof(int32_t)); + if(stereo) + memcpy(st->ovl_buff[1], buf_in[1]+i, st->ovl_size * sizeof(int32_t)); + } + + return dest[0] - buf_out[0]; +} + +#if 0 +static int tdspeed_next_required_space(int data_len, int last) +{ + struct tdspeed_state_s *st = &tdspeed_state; + int src_frame_sz, src_size, nb_frames, dst_space; + + src_frame_sz = st->shift_max + st->dst_step; + if (st->dst_step > st->src_step) + src_frame_sz += st->dst_step - st->src_step; + src_size = data_len + st->ovl_size; + if (st->ovl_shift > 0) + src_size -= st->ovl_shift; + if (src_size < src_frame_sz) { + if (!last) + return 0; + dst_space = data_len + st->ovl_size; + if (st->ovl_shift < 0) + dst_space += st->ovl_shift; + } else { + nb_frames = (src_size - src_frame_sz) / st->src_step + 1; + dst_space = nb_frames * st->dst_step; + if (last) { + dst_space += src_size - nb_frames * st->src_step; + dst_space += st->src_step - st->dst_step; + } + } + return dst_space; +} +#endif + +long tdspeed_est_output_size(long size) +{ + //int _size = size; +#if 0 + size = tdspeed_next_required_space(size, false); + if(size > TDSPEED_OUTBUFSIZE) + size = TDSPEED_OUTBUFSIZE; +#else + size = TDSPEED_OUTBUFSIZE; +#endif + mylog("tdspeed_est_output_size of %d -> %d\n", _size, size); + return size; +} +long tdspeed_est_input_size(long size) +{ + struct tdspeed_state_s *st = &tdspeed_state; + //int _size = size; + size = (size -st->ovl_size) *st->src_step /st->dst_step; + if(size <0) + size = 0; + else size = size; + mylog("tdspeed_est_input_size of %d -> %d\n", _size, size); + return size; +} + +int tdspeed_doit(int32_t *src[], int count) +{ + mylog("tdspeed_doit %d\n", count); + count = tdspeed_apply( (int32_t *[2]) { outbuf[0], outbuf[1] }, + src, count, 0, TDSPEED_OUTBUFSIZE); + src[0] = outbuf[0]; + src[1] = outbuf[1]; + return count; +} diff -Naur _009/apps/tdspeed.h _010/apps/tdspeed.h --- _009/apps/tdspeed.h 1970-01-01 09:00:00.000000000 +0900 +++ _010/apps/tdspeed.h 2008-09-10 21:20:31.879900800 +0900 @@ -0,0 +1,9 @@ +#define TDSPEED_OUTBUFSIZE 4096 + +bool tdspeed_init(int samplerate, bool stereo, int factor); +int tdspeed_apply(int32_t *buf_out[2], int32_t *buf_in[2], int data_len, + int last, int out_size); + +long tdspeed_est_output_size(long size); +long tdspeed_est_input_size(long size); +int tdspeed_doit(int32_t *src[], int count); diff -Naur _009/docs/CREDITS _010/docs/CREDITS --- _009/docs/CREDITS 2008-09-10 06:57:41.000000000 +0900 +++ _010/docs/CREDITS 2008-09-10 21:58:58.236278400 +0900 @@ -418,6 +418,7 @@ Volker Mische Vitja Makarov Francisco Vila +Nicolas Pitre The libmad team The wavpack team