📄 dwvw.c
字号:
/*** Copyright (C) 2002-2004 Erik de Castro Lopo <erikd@mega-nerd.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU Lesser General Public License as published by** the Free Software Foundation; either version 2.1 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU Lesser General Public License for more details.**** You should have received a copy of the GNU Lesser General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//*===========================================================================** Delta Word Variable Width**** This decoder and encoder were implemented using information found in this** document : http://home.swbell.net/rubywand/R011SNDFMTS.TXT**** According to the document, the algorithm "was invented 1991 by Magnus** Lidstrom and is copyright 1993 by NuEdge Development".*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "sndfile.h"#include "config.h"#include "sfendian.h"#include "float_cast.h"#include "common.h"typedef struct{ int dwm_maxsize, bit_width, max_delta, span ; int samplecount ; int bit_count, bits, last_delta_width, last_sample ; struct { int index, end ; unsigned char buffer [256] ; } b ;} DWVW_PRIVATE ;/*============================================================================================*/static sf_count_t dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t dwvw_write_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t dwvw_write_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t dwvw_write_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t dwvw_write_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t dwvw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;static int dwvw_close (SF_PRIVATE *psf) ;static int dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len) ;static int dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count) ;static int dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len) ;static void dwvw_encode_store_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int data, int new_bits) ;static void dwvw_read_reset (DWVW_PRIVATE *pdwvw) ;/*============================================================================================** DWVW initialisation function.*/intdwvw_init (SF_PRIVATE *psf, int bitwidth){ DWVW_PRIVATE *pdwvw ; if (bitwidth > 24) return SFE_DWVW_BAD_BITWIDTH ; if (psf->mode == SFM_RDWR) return SFE_BAD_MODE_RW ; if ((pdwvw = calloc (1, sizeof (DWVW_PRIVATE))) == NULL) return SFE_MALLOC_FAILED ; psf->fdata = (void*) pdwvw ; pdwvw->bit_width = bitwidth ; pdwvw->dwm_maxsize = bitwidth / 2 ; pdwvw->max_delta = 1 << (bitwidth - 1) ; pdwvw->span = 1 << bitwidth ; dwvw_read_reset (pdwvw) ; if (psf->mode == SFM_READ) { psf->read_short = dwvw_read_s ; psf->read_int = dwvw_read_i ; psf->read_float = dwvw_read_f ; psf->read_double = dwvw_read_d ; } ; if (psf->mode == SFM_WRITE) { psf->write_short = dwvw_write_s ; psf->write_int = dwvw_write_i ; psf->write_float = dwvw_write_f ; psf->write_double = dwvw_write_d ; } ; psf->seek = dwvw_seek ; psf->close = dwvw_close ; /* FIXME : This s bogus. */ psf->sf.frames = SF_COUNT_MAX ; psf->datalength = psf->sf.frames ; /* EMXIF : This s bogus. */ return 0 ;} /* dwvw_init *//*--------------------------------------------------------------------------------------------*/static intdwvw_close (SF_PRIVATE *psf){ DWVW_PRIVATE *pdwvw ; if (psf->fdata == NULL) return 0 ; pdwvw = (DWVW_PRIVATE*) psf->fdata ; if (psf->mode == SFM_WRITE) { static int last_values [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; /* Write 8 zero samples to fully flush output. */ dwvw_encode_data (psf, pdwvw, last_values, 12) ; /* Write the last buffer worth of data to disk. */ psf_fwrite (pdwvw->b.buffer, 1, pdwvw->b.index, psf) ; if (psf->write_header) psf->write_header (psf, SF_TRUE) ; } ; return 0 ;} /* dwvw_close */static sf_count_tdwvw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset){ DWVW_PRIVATE *pdwvw ; mode = mode ; if (! psf->fdata) { psf->error = SFE_INTERNAL ; return ((sf_count_t) -1) ; } ; pdwvw = (DWVW_PRIVATE*) psf->fdata ; if (offset == 0) { psf_fseek (psf, psf->dataoffset, SEEK_SET) ; dwvw_read_reset (pdwvw) ; return 0 ; } ; psf->error = SFE_BAD_SEEK ; return ((sf_count_t) -1) ;} /* dwvw_seek *//*==============================================================================*/static sf_count_tdwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len){ DWVW_PRIVATE *pdwvw ; int *iptr ; int k, bufferlen, readcount = 0, count ; sf_count_t total = 0 ; if (! psf->fdata) return 0 ; pdwvw = (DWVW_PRIVATE*) psf->fdata ; iptr = psf->u.ibuf ; bufferlen = ARRAY_LEN (psf->u.ibuf) ; while (len > 0) { readcount = (len >= bufferlen) ? bufferlen : len ; count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ; for (k = 0 ; k < readcount ; k++) ptr [total + k] = iptr [k] >> 16 ; total += count ; len -= readcount ; if (count != readcount) break ; } ; return total ;} /* dwvw_read_s */static sf_count_tdwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len){ DWVW_PRIVATE *pdwvw ; int readcount, count ; sf_count_t total = 0 ; if (! psf->fdata) return 0 ; pdwvw = (DWVW_PRIVATE*) psf->fdata ; while (len > 0) { readcount = (len > 0x10000000) ? 0x10000000 : (int) len ; count = dwvw_decode_data (psf, pdwvw, ptr, readcount) ; total += count ; len -= count ; if (count != readcount) break ; } ; return total ;} /* dwvw_read_i */static sf_count_tdwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len){ DWVW_PRIVATE *pdwvw ; int *iptr ; int k, bufferlen, readcount = 0, count ; sf_count_t total = 0 ; float normfact ; if (! psf->fdata) return 0 ; pdwvw = (DWVW_PRIVATE*) psf->fdata ; normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ; iptr = psf->u.ibuf ; bufferlen = ARRAY_LEN (psf->u.ibuf) ; while (len > 0) { readcount = (len >= bufferlen) ? bufferlen : len ; count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ; for (k = 0 ; k < readcount ; k++) ptr [total + k] = normfact * (float) (iptr [k]) ; total += count ; len -= readcount ; if (count != readcount) break ; } ; return total ;} /* dwvw_read_f */static sf_count_tdwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len){ DWVW_PRIVATE *pdwvw ; int *iptr ; int k, bufferlen, readcount = 0, count ; sf_count_t total = 0 ; double normfact ; if (! psf->fdata) return 0 ; pdwvw = (DWVW_PRIVATE*) psf->fdata ; normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ; iptr = psf->u.ibuf ; bufferlen = ARRAY_LEN (psf->u.ibuf) ; while (len > 0) { readcount = (len >= bufferlen) ? bufferlen : len ; count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ; for (k = 0 ; k < readcount ; k++) ptr [total + k] = normfact * (double) (iptr [k]) ; total += count ; len -= readcount ; if (count != readcount) break ; } ; return total ;} /* dwvw_read_d */static intdwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len){ int count ; int delta_width_modifier, delta_width, delta_negative, delta, sample ; /* Restore state from last decode call. */ delta_width = pdwvw->last_delta_width ; sample = pdwvw->last_sample ; for (count = 0 ; count < len ; count++) { /* If bit_count parameter is zero get the delta_width_modifier. */ delta_width_modifier = dwvw_decode_load_bits (psf, pdwvw, -1) ; /* Check for end of input bit stream. Break loop if end. */ if (delta_width_modifier < 0) break ; if (delta_width_modifier && dwvw_decode_load_bits (psf, pdwvw, 1)) delta_width_modifier = - delta_width_modifier ; /* Calculate the current word width. */ delta_width = (delta_width + delta_width_modifier + pdwvw->bit_width) % pdwvw->bit_width ; /* Load the delta. */ delta = 0 ; if (delta_width) { delta = dwvw_decode_load_bits (psf, pdwvw, delta_width - 1) | (1 << (delta_width - 1)) ; delta_negative = dwvw_decode_load_bits (psf, pdwvw, 1) ; if (delta == pdwvw->max_delta - 1) delta += dwvw_decode_load_bits (psf, pdwvw, 1) ; if (delta_negative) delta = -delta ; } ; /* Calculate the sample */ sample += delta ; if (sample >= pdwvw->max_delta) sample -= pdwvw->span ; else if (sample < - pdwvw->max_delta) sample += pdwvw->span ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -