翻译c代码,在线等!(200分)

  • 主题发起人 主题发起人 wuchunhua
  • 开始时间 开始时间
W

wuchunhua

Unregistered / Unconfirmed
GUEST, unregistred user!
//用delphi实现下面代码
#include "adpcm.h"
#include <stdio.h> /*DBG*/

#ifndef __STDC__
#define signed
#endif

/* Intel ADPCM step variation table */
static int indexTable[16] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8,
};

static int stepsizeTable[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};

void
adpcm_coder(indata, outdata, len, state)
short indata[];
char outdata[];
int len;
struct adpcm_state *state;
{
short *inp;
/*input buffer pointer */
signed char *outp; /* output buffer pointer */
int val; /* Current input sample value */
int sign; /* Current adpcm sign bit */
int delta; /* Current adpcm output value */
int diff; /* Difference between val and valprev */
int step; /* Stepsize */
int valpred; /* Predicted output value */
int vpdiff; /* Current change to valpred */
int index; /* Current step change index */
int outputbuffer; /* place to keep previous 4-bit value */
int bufferstep; /* toggle between outputbuffer/output */

outp = (signed char *)outdata;
inp = indata;

valpred = state->valprev;
index = state->index;
step = stepsizeTable[index];

bufferstep = 1;

for ( ;
len > 0 ;
len-- ) {
val = *inp++;

/* Step 1 - compute difference with previous value */
diff = val - valpred;
sign = (diff < 0) ? 8 : 0;
if ( sign ) diff = (-diff);

/* Step 2 - Divide and clamp */
/* Note:
** This code *approximately* computes:
** delta = diff*4/step;
** vpdiff = (delta+0.5)*step/4;
** but in shift step bits are dropped. The net result of this is
** that even if you have fast mul/div hardware you cannot put it to
** good use since the fixup would be too expensive.
*/
delta = 0;
vpdiff = (step >> 3);

if ( diff >= step ) {
delta = 4;
diff -= step;
vpdiff += step;
}
step >>= 1;
if ( diff >= step ) {
delta = delta|2;
diff -= step;
vpdiff += step;
}
step >>= 1;
if ( diff >= step ) {
delta |= 1;
vpdiff += step;
}

/* Step 3 - Update previous value */
if ( sign )
valpred -= vpdiff;
else

valpred += vpdiff;

/* Step 4 - Clamp previous value to 16 bits */
if ( valpred > 32767 )
valpred = 32767;
else
if ( valpred < -32768 )
valpred = -32768;

/* Step 5 - Assemble value, update index and step values */
delta |= sign;

index += indexTable[delta];
if ( index < 0 ) index = 0;
if ( index > 88 ) index = 88;
step = stepsizeTable[index];

/* Step 6 - Output value */
if ( bufferstep ) {
outputbuffer = (delta << 4) & 0xf0;
} else
{
*outp++ = (delta & 0x0f) | outputbuffer;
}
bufferstep = !bufferstep;
}

/* Output last step, if needed */
if ( !bufferstep )
*outp++ = outputbuffer;

state->valprev = valpred;
state->index = index;
}

void
adpcm_decoder(indata, outdata, len, state)
char indata[];
short outdata[];
int len;
struct adpcm_state *state;
{
signed char *inp; /* Input buffer pointer */
short *outp; /* output buffer pointer */
int sign; /* Current adpcm sign bit */
int delta; /* Current adpcm output value */
int step; /* Stepsize */
int valpred; /* Predicted value */
int vpdiff; /* Current change to valpred */
int index; /* Current step change index */
int inputbuffer; /* place to keep next 4-bit value */
int bufferstep; /* toggle between inputbuffer/input */

outp = outdata;
inp = (signed char *)indata;

valpred = state->valprev;
index = state->index;
step = stepsizeTable[index];

bufferstep = 0;

for ( ;
len > 0 ;
len-- ) {

/* Step 1 - get the delta value */
if ( bufferstep ) {
delta = inputbuffer & 0xf;
} else
{
inputbuffer = *inp++;
delta = (inputbuffer >> 4) & 0xf;
}
bufferstep = !bufferstep;

/* Step 2 - Find new index value (for later) */
index += indexTable[delta];
if ( index < 0 ) index = 0;
if ( index > 88 ) index = 88;

/* Step 3 - Separate sign and magnitude */
sign = delta & 8;
delta = delta & 7;

/* Step 4 - Compute difference and new predicted value */
/*
** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
** in adpcm_coder.
*/
vpdiff = step >> 3;
if ( delta & 4 ) vpdiff += step;
if ( delta & 2 ) vpdiff += step>>1;
if ( delta & 1 ) vpdiff += step>>2;

if ( sign )
valpred -= vpdiff;
else

valpred += vpdiff;

/* Step 5 - clamp output value */
if ( valpred > 32767 )
valpred = 32767;
else
if ( valpred < -32768 )
valpred = -32768;

/* Step 6 - Update step value */
step = stepsizeTable[index];

/* Step 7 - Output value */
*outp++ = valpred;
}

state->valprev = valpred;
state->index = index;
}
 
//以下翻译出现错误,当把一个数组A编码(adpcmencoder函数)得到数组B,然后把B进行解码(adpcmdecoder函数)得到C,结果A不等于C.理论上应该是一样的
unit ADPCM;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
adpcmstate = Record
valprev:integer;
index:integer
end;

var
FState : adpcmstate ;
procedure adpcmencoder(indata:array of smallint;var outdata:array of shortint;len:integer;state:adpcmstate);
procedure adpcmdecoder(indata:array of shortint;var outdata:array of smallint;len:integer;state:adpcmstate);

const
indextable:array[0..15] of integer=(
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
);
stepsizetable:array[0..88] of integer=(
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
);

implementation



procedure adpcmencoder(indata:array of smallint;var outdata:array of shortint;len:integer;state:adpcmstate);
var
inp,outp,i,val,sign,delta,diff,step,valpred,vpdiff,index,outputbuffer:integer;
bufferstep:boolean;
begin

outp:=0;
inp:=0;

valpred:=state.valprev;
index:=state.index;
step:=stepsizetable[index];

bufferstep:=true;
outputbuffer:=0;

for i:=1 to lendo

begin

val:=indata[inp];
inp:=inp+1;
diff:=val-valpred;
if diff<0 then
sign:=8 else
sign:=0;
if sign<>0 then
diff:=-diff;

delta:=0;
vpdiff:=step shr 3;

if diff>=step then

begin

delta:=4;
diff:=diff-step;
vpdiff:=vpdiff+step;
end;

step:=step shr 1;
if diff>=step then

begin

delta:=delta or 2;
diff:=diff-step;
vpdiff:=vpdiff+step;
end;

step:=step shr 1;
if diff>=step then

begin

delta:=delta or 1;
vpdiff:=vpdiff+step;
end;


if sign<>0 then
valpred:=valpred-vpdiff
else
valpred:=valpred+vpdiff;

if valpred>32767 then
valpred:=32767
else
if valpred<-32768 then
valpred:=-32768;

delta:=delta or sign;

index:=index+indextable[delta];

if index<0 then
index:=0;
if index>88 then
index:=88;
step:=stepsizetable[index];

if bufferstep then
outputbuffer:=(delta shl 4) and $f0
else

begin

outdata[outp]:=(delta and $0f) or outputbuffer;
outp:=outp+1;
end;

bufferstep:= not bufferstep;
end;

if not bufferstep then

begin

outdata[outp]:=outputbuffer;
outp:=outp+1;
end;


state.valprev:=valpred;
state.index:=index;
end;


procedure adpcmdecoder(indata:array of shortint;var outdata:array of smallint;len:integer;state:adpcmstate);
var
inp,outp,i,sign,delta,step,valpred,vpdiff,index,inputbuffer:integer;
bufferstep:boolean;
begin

outp:=0;
inp:=0;

valpred:=state.valprev;
index:=state.index;
step:=stepsizetable[index];

bufferstep:=false;
inputbuffer:=0;

for i:=1 to lendo

begin

if bufferstep then
delta:=inputbuffer and $0f
else

begin

inputbuffer:=indata[inp];
inp:=inp+1;
delta:=(inputbuffer shr 4) and $0f
end;

bufferstep:= not bufferstep;
index:=index+indextable[delta];
if index<0 then
index:=0;
if index>88 then
index:=88;

sign:=delta and 8;
delta:=delta and 7;

vpdiff:=step shr 3;

if (delta and 4)<>0 then
vpdiff:=vpdiff+step;
if (delta and 2)<>0 then
vpdiff:=vpdiff+(step shr 1);
if (delta and 1)<>0 then
vpdiff:=vpdiff+(step shr 2);

if sign<>0 then
valpred:=valpred-vpdiff
else
valpred:=valpred+vpdiff;

if valpred>32767 then
valpred:=32767
else
if valpred<-32768 then
valpred:=-32768;

step:=stepsizetable[index];

outdata[outp]:=valpred;
outp:=outp+1;
end;


state.valprev:=valpred;
state.index:=index;
end;


end.
 
帮顶有分!
 
unit Adpcm;

interface

uses
SysUtils, Dialogs;

type
adpcm_state = record
valprev: integer;
index: integer;
end;


procedure adpcm_coder(indata, outdata: Pointer;
len: Integer;
var state: adpcm_state);
procedure adpcm_decoder(indata, outdata: Pointer;
len: Integer;
var state: adpcm_state);

implementation

const
indexTable: array[0..15] of integer =
(
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
);

stepsizeTable: array[0..88] of integer =
(
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
);


procedure adpcm_coder(indata, outdata: Pointer;
len: Integer;
var state: adpcm_state);
var
inp: PSmallInt;
outp: PShortint;
val: Integer;
sign: Integer;
delta: Integer;
diff: Integer;
step: Integer;
valpred: Integer;
vpdiff: Integer;
index: Integer;
outputbuffer: Integer;
bufferstep: Boolean;

i: integer;
begin

inp:=PSmallInt(indata);
outp:=PShortint(outdata);

valpred := state.valprev;
index := state.index;
step := stepsizeTable[index];
bufferstep := True;
outputbuffer := 0;

for i:=len div 2do
wnto 1do

begin

val := SmallInt(inp^);
Inc(inp);
diff := val - valpred;
if diff<0 then
sign:=8 else
sign:=0;
if sign<>0 then
diff:=-diff;
delta := 0;
vpdiff := (step shr 3);
if ( diff >= step ) then

begin

delta := 4;
diff := diff - step;
vpdiff := vpdiff + step;
end;

step := step shr 1;
if ( diff >= step ) then

begin

delta := delta or 2;
diff := diff - step;
vpdiff := vpdiff + step;
end;

step := step shr 1;
if ( diff >= step ) then

begin

delta := delta or 1;
vpdiff := vpdiff + step;
end;

if ( sign <> 0 ) then
valpred := valpred - vpdiff
else
valpred := valpred + vpdiff;
if ( valpred > 32767 ) then
valpred := 32767
else
if ( valpred < -32768 ) then
valpred := -32768;
delta := delta or sign;
index := index + indexTable[delta];
if ( index < 0 ) then
index := 0;
if ( index > 88 ) then
index := 88;
step := stepsizeTable[index];

if bufferstep then
outputbuffer := (delta shl 4) and $F0
else
begin

outp^ := (delta and $F) or outputbuffer;
Inc(outp);
end;

bufferstep := not bufferstep;
end;

if not bufferstep then
outp^ := outputbuffer;
state.valprev := valpred;
state.index := index;
end;


procedure adpcm_decoder(indata, outdata: Pointer;
len: Integer;
var state: adpcm_state);
var
inp: PShortint;
outp: PSmallInt;
sign: Integer;
delta: Integer;
step: Integer;
valpred: Integer;
vpdiff: Integer;
index: Integer;
inputbuffer: Integer;
bufferstep: Boolean;


i: integer;
begin

inp:=PShortint(indata);
outp:=PSmallInt(outdata);

valpred := state.valprev;
index := state.index;
step := stepsizeTable[index];
bufferstep := False;
inputbuffer:=0;

for i:=lendo
wnto 1do

begin

if bufferstep then
delta := inputbuffer and $F
else
begin

inputbuffer := Shortint(inp^);
Inc(inp);
delta := (inputbuffer shr 4) and $F;
end;

bufferstep := not bufferstep;
index := index + indexTable[delta];
if ( index < 0 ) then
index := 0;
if ( index > 88 ) then
index := 88;
sign := delta and 8;
delta := delta and 7;
vpdiff := step shr 3;
if ( delta and 4 ) <> 0 then
vpdiff := vpdiff + step;
if ( delta and 2 ) <> 0 then
vpdiff := vpdiff + step shr 1;
if ( delta and 1 ) <> 0 then
vpdiff := vpdiff + step shr 2;
if ( sign <> 0 ) then
valpred := valpred - vpdiff
else
valpred := valpred + vpdiff;
if ( valpred > 32767 ) then
valpred := 32767
else
if ( valpred < -32768 ) then
valpred := -32768;
step := stepsizeTable[index];
outp^ := valpred;
Inc(outp);
end;

state.valprev := valpred;
state.index := index;
end;


end.



//--------------调用
procedure TForm1.Button1Click(Sender: TObject);
var
ina: array[0..15] of SmallInt;
outa: array[0..15] of ShortInt;
state: adpcm_state;
i: integer;
begin

Memo1.Clear;
FillChar(ina, SizeOf(ina), 0);
FillChar(outa, SizeOf(outa), 0);
ina[0]:=555;
ina[1]:=99;
ina[2]:=23;
ina[3]:=93;
ina[4]:=103;
ina[5]:=565;
state.valprev:=0;
state.index:=0;
adpcm_coder(@ina, @outa, SizeOf(ina), state);
state.valprev:=0;
state.index:=0;
adpcm_decoder(@outa, @ina, SizeOf(outa),state);
for i:=Low(ina) to high(ina)do

Memo1.Lines.add(IntToStr(ina));
end;
 
to:luzhouman
//你翻译的和我前面的没有什么区别,就是当把一个数组A编码(adpcmencoder函数)得到数组B,然后把B进行解码(adpcmdecoder函数)得到C,结果A不等于C.理论上应该是一样的.
真是头疼,我其实要实现的是ADPCM编码.
 
ADPCM是有损音频编码格式, 理论上 A<>C, 我上面转的有点错,改了
 
问题和奇怪,当捕捉到的音频数据不经过上面的adpcm编码,直接传送过去,声音可以播放,可是经过上面编码得到了一个新的数据,就什么都听不到,问题出在那里,希望大家多多帮助,上面的翻译和我的结果是一样的,luzhouman 分会给你的,不过要等等
 
你是如何编码的, 加wav头没有
 
呵呵好多代码啊
看不下去了
帮你顶一下
 
mmtools 有个处理单元MMADPCM.pas, 可以参考一下
 
感觉ADPCM只能处理16-bit PCM样本,我是用API函数实现音频捕捉的,当缓存满了触发MM_WIM_DATA消息,->Header:= PWaveHdr(msg.lparam)->Move(header.lpdata,sbuf[0],inlength);得到这么一个数组,在把数组进行编码
 
多人接受答案了。
 
后退
顶部