急!! Delphi 代码转换为 C 代码.... ( 我写的有错?? )
C 代码编译成 DLL 文件后, 执行结果与 Delphi 的 DLL 结果不一样.
代码如下:
///////////////////////////////////////////////
//
// Delphi 代码
//
///////////////////////////////////////////////
const
constACMAdptive: array[0..15] of SmallInt = (230, 230, 230, 230, 307, 409,
512, 614, 768, 614, 512, 409, 307, 230, 230, 230);
constACMCoef: array[0..1, 0..6] of SmallInt = (
(256, 512, 0, 192, 240, 460, 392),
(0, -256, 0, 64, 0, -208, -232));
procedure CreateACMData(Source: array of Byte; var Dest: array of SmallInt);
var
i, j, Prec: Integer;
Sample, Delta: LongInt;
Samp1, Samp2: SmallInt;
Code: Byte;
begin
Prec := Source[0];
Delta := (Source[2] shl 8) or Source[1];
Samp1 := (Source[4] shl 8) or Source[3];
Samp2 := (Source[6] shl 8) or Source[5];
Dest[0] := Samp2;
Dest[1] := Samp1;
for i := 0 to 248 do
begin
for j := 0 to 1 do
begin
if j = 0 then
begin
Code :=(Source[i + 7] and $0F0);
Code := Code shr 4;
end
else begin
Code := Source[i + 7] and $0F;
end;
Sample := (Samp1 * constACMCoef[0, Prec] + Samp2 *
constACMCoef[1, Prec]) div 256;
if (Code > 7) then
begin
Sample := Sample + Delta * (Code - $10);
end
else begin
Sample := Sample + Delta * Code;
end;
if Sample > 32767 then
begin
Sample := 32767;
end;
if Sample < -32768 then
begin
Sample := -32768;
end;
Dest[i * 2 + j + 2] := Sample;
Delta := (Delta * constACMAdptive[Code]) div 256;
if Delta < 16 then
begin
Delta := 16;
end;
Samp2 := Samp1;
Samp1 := Sample;
end;
end;
end;
///////////////////////////////////////////////
//
// C 代码
//
///////////////////////////////////////////////
short constACMAdptive[16] = {230, 230, 230, 230, 307, 409,
512, 614, 768, 614, 512, 409, 307, 230, 230, 230};
short constACMCoef[2][7] = {
{256, 512, 0, 192, 240, 460, 392},
{0, -256, 0, 64, 0, -208, -232}};
void WINAPI CreateACMData(byte *Source, short *Dest)
{
int i, j, Prec;
LONG Sample, Delta;
short Samp1, Samp2;
byte Code;
Prec = Source[0];
Delta = (Source[2] << 8) | Source[1];
Samp1 = (Source[4] << 8) | Source[3];
Samp2 = (Source[6] << 8) | Source[5];
Dest[0] = Samp2;
Dest[1] = Samp1;
for (i = 0; i <= 248; i++)
{
for (j = 0; j <= 1; j++)
{
Code = (j==0) ? ((Source[i + 7] & 0xF0) >> 4) : (Source[i + 7] & 0x0F);
Sample = (Samp1 * constACMCoef[0][Prec] + Samp2 * constACMCoef[1][Prec]) / 256;
Sample = (Code > 7) ? (Sample + Delta * (Code - 0x10)) : (Sample + Delta * Code);
Sample = (Sample > 32767) ? 32767 : Sample;
Sample = (Sample < -32768) ? -32768 : Sample;
Dest[i * 2 + j + 2] = (byte)Sample;
Delta = (Delta * constACMAdptive[Code]) / 256;
Delta = (Delta < 16) ? 16 : Delta;
Samp2 = Samp1;
Samp1 = (short)Sample;
}
}
}
问题点数:200、回复次数:15Top
1 楼cmain83(C 写紫色天空)回复于 2005-06-21 16:57:40 得分 0
upTop
2 楼beyondtkl(大龙驹<*好久没来了,兄弟们好吧。*>)回复于 2005-06-21 17:07:31 得分 10
procedure CreateACMData(Source: array of Byte; var Dest: array of SmallInt);
void WINAPI CreateACMData(byte *Source, short *Dest)
// 还是用
procedure CreateACMData(Source:PByte; Dest:PShort);stdcall; 吧。。
里面 用一个指针 指向其首地址 然后移动即可 。。。
Top
3 楼cmain83(C 写紫色天空)回复于 2005-06-21 17:18:19 得分 0
beyondtkl(大龙驹<*飞的更高*>)
还同明白我的意思??
如何引用已经没问题. 这一点是肯定.
只是内部代码哪里出了问题我却一直找不到.Top
4 楼constantine(飘遥的安吉儿)回复于 2005-06-21 17:58:07 得分 160
Prec = Source[0];
...
Sample = (Samp1 * constACMCoef[0][Prec] + Samp2 * constACMCoef[1][Prec]) / 256;
这样的代码什么意思?你传入的Source[0]如果大过原来的数组边界,那么
constACMCoef[1][Prec]
constACMCoef[0][Prec]
这2个是什么东西来的,根本就乱了么,我设置了断点一看sample的值都不一样了,以后怎么可能一样
我测试的数组Source[0]=230;
所以不知道是你的测试的东西都很小还是什么?
你设置断点一步一步跟踪下去就知道了,看看那里的值不一样
Top
5 楼constantine(飘遥的安吉儿)回复于 2005-06-21 18:01:53 得分 0
如果不是这个问题回头再看
如果从代码转换角度看,没有看出问题来Top
6 楼jadeluo(秀峰)回复于 2005-06-21 18:19:27 得分 10
我觉得问题可能出在C的位移操作与Delphi的不同上。
因为楼主的代码本身存在着一个编译器有关的问题,就是这些的语句:
Delta := (Source[2] shl 8) or Source[1];
Samp1 := (Source[4] shl 8) or Source[3];
Samp2 := (Source[6] shl 8) or Source[5];
这里的Source是array of Byte, 既然是Byte,那么shl 8结果应该是什么呢?
是0?还是因为最终的值是赋给了LongInt或者SmallInt而不是0呢?
换成C之后是不是还是这样的结果呢?
我想这个没有特定的答案,这个要取决于用什么样的编译器了。
建议楼主改成:
Delta := Source[2];
Delta := (Delta shl 8) or Source[1];
Samp1 := Source[4];
Samp1 := (Samp1 shl 8) or Source[3];
Samp2 := Source[6];
Samp2 := (Samp2 shl 8) or Source[5];
Top
7 楼rouqing(*冰雨&双子座奇缘*)回复于 2005-06-22 01:11:54 得分 10
mark...upTop
8 楼cmain83(C 写紫色天空)回复于 2005-06-22 09:24:18 得分 0
Delphi 的代码绝对没有问题, 这是已经通过的成熟代码.
现在要做的是把它转换为C
TO constantine(飘遥的安吉儿)
constACMCoef 是一个常量二维数组.
传入的参数
byte *Source, short *Dest
Source 是一个指向数组首地址的指针.
并且, Source 里的值都是很小的...
此函数的调用如下.( 已经固定的模式的 )
byte Source[256];
short Dest[500];
从一个文件中读取256个值放入Source中
CreateACMData(&Source, &Dest);
Top
9 楼constantine(飘遥的安吉儿)回复于 2005-06-22 11:06:50 得分 0
不是位操作的问题,我一步一步跟踪的时候,那部分结果是一样的
搂住:你说的我知道,那么起码你的代码安全性不好,随便就可以越界了
就算小,到底多大,都没有超过6吗?后面也都没有?
最好给组测试例子,数组测试的时候10个就够了
还有完善你的代码,你的第一位用来干什么的?保证真的不超过数组边界吗?Top
10 楼cmain83(C 写紫色天空)回复于 2005-06-22 15:54:42 得分 0
呵呵,谢谢你的提醒。
这是以后的任务
现在最主要的是转换到C语言。
至于值的大小,这一点不用担心。
这其实是一个解压缩的代码。。。压缩比为4:1(ADPCM)
一个byte数值它保存了两个压缩后的数据,所以,并且每4位中就有一位是符号位,
所以不用担心越界。
之所以不改用其它的算法,是因为我们的硬件不能改写。
我的QQ是33591840
明天一起交流。。。
我现在不行。 还有其它很重要的事,并且不在自己的电脑。
非常感谢关注Top
11 楼beyondtkl(大龙驹<*好久没来了,兄弟们好吧。*>)回复于 2005-06-22 16:06:08 得分 10
此函数的调用如下.( 已经固定的模式的 )
byte Source[256];
short Dest[500];
从一个文件中读取256个值放入Source中
CreateACMData(&Source, &Dest);
------------>
不对吧。。。Source就是首地址了。。。Source == &Source[0]; 看看 是不是这个错误?Top
12 楼constantine(飘遥的安吉儿)回复于 2005-06-23 08:33:14 得分 0
传入的时候把数组名字传入就可以了,数组名就是数组的指针,指向其其实地址
CreateACMData(Source, Dest);
这样就可以了Top
13 楼cmain83(C 写紫色天空)回复于 2005-06-23 08:55:18 得分 0
我试了还是不行啊...:(Top
14 楼cmain83(C 写紫色天空)回复于 2005-06-23 17:33:06 得分 0
upTop
15 楼cmain83(C 写紫色天空)回复于 2005-07-02 10:59:11 得分 0
没有帮忙,,, 自己搞乎三天搞定...
得谢谢
constantine(飘遥的安吉儿)
提醒: 设置断点一步一步执行.( 我以前从来不进行单步执行程序来调试程序,觉得太要时间,
现在发现这样也好处多多. )
也同时贴出代码
void WINAPI CreateACMData(byte *Source, short *Dest)
{
int i, j, Prec;
LONG Sample, Delta;
short Samp1, Samp2;
byte Code;
Prec = Source[0];
Delta = (Source[2] << 8) | Source[1];
Samp1 = (Source[4] << 8) | Source[3];
Samp2 = (Source[6] << 8) | Source[5];
Dest[0] = Samp2;
Dest[1] = Samp1;
for (i = 0; i <= 248; i++)
{
for (j = 0; j <= 1; j++)
{
Code = (j==0) ? ((Source[i + 7] & 0xF0) >> 4) : (Source[i + 7] & 0x0F);
Sample = (Samp1 * constACMCoef[0][Prec] + Samp2 * constACMCoef[1][Prec]) / 256;
Sample = (Code > 7) ? (Sample + Delta * (Code - 0x10)) : (Sample + Delta * Code);
Sample = (Sample > 32767) ? 32767 : Sample;
Sample = (Sample < -32768) ? -32768 : Sample;
Dest[i * 2 + j + 2] = (short)Sample;
Delta = (Delta * constACMAdptive[Code]) / 256;
Delta = (Delta < 16) ? 16 : Delta;
Samp2 = Samp1;
Samp1 = (short)Sample;
}
}
}
出错在:
Dest[i * 2 + j + 2] = (byte)Sample;
正确:
Dest[i * 2 + j + 2] = (short)Sample;
这时粗心所造成. 但是这个贴子也值.
因为我用单步调试解决了另一个很头痛复杂问题.
呵呵.希望各位写代码不要粗心... 不然, 你会很痛苦D...
:)Top




