erik_nodland
asked on
Need help with a weird problem I can't fix
Hi All,
I have an application that accepts audio data every 20ms. I decode the data and write it to disk. The problem is that I am getting corrupt data when I include some lines of code. Below will explain what I mean. Ultimately what I want to do is decode both inbound and outbound streams and mix them before writing. The trouble is as soon as I try and decode the ourbound stream something gets screwed.
See comments below:
byte[] InboundG729L1 = new byte[10], InboundG729L2 = new byte[10];
byte[] OutboundG729L1 = new byte[10], OutboundG729L2 = new byte[10];
short[] InboundDecodedG729L1 = new short[80], InboundDecodedG729L2 = new short[80];
short[] OutboundDecodedG729L1 = new short[80], OutboundDecodedG729L2 = new short[80];
short[] inbound = new short[160], outbound = new short[160];
short result = 0;
byte retval;
//Copy both halves of the RTP data into seperate arrays
Buffer.BlockCopy(inboundRT P.RTPPaylo ad, 0, InboundG729L1, 0, 10);
Buffer.BlockCopy(inboundRT P.RTPPaylo ad, 10, InboundG729L2, 0, 10);
Buffer.BlockCopy(outboundR TP.RTPPayl oad, 0, OutboundG729L1, 0, 10);
Buffer.BlockCopy(outboundR TP.RTPPayl oad, 10, OutboundG729L2, 0, 10);
//Decode first half of data
IntPtr p = Global.decode(InboundG729L 1);
Marshal.Copy(p, InboundDecodedG729L1, 0, 80);
Global.freemem(p);
//Decode second half of data
p = Global.decode(InboundG729L 2);
Marshal.Copy(p, InboundDecodedG729L2, 0, 80);
Global.freemem(p);
//****** If I uncomment the following 3 lines the data comes out corrupted. It is fine as long as they remain commented
//****** As you can see the 3 lines shouldn;t have any effect on what I am writing to disk.
//****** Ultimately I want to use the decoded output from below to mix both streams together.
//p = Global.decode(OutboundG729 L1);
//Marshal.Copy(p, OutboundDecodedG729L1, 0, 80);
//Global.freemem(p);
//Copy both arrays of decoded data into one array ready to write to disk
Buffer.BlockCopy(InboundDe codedG729L 1, 0, inbound, 0, InboundDecodedG729L1.Lengt h * 2); //Multiply by 2 because it is a byte offset and we are dealing with 16bits
Buffer.BlockCopy(InboundDe codedG729L 2, 0, inbound, 160, InboundDecodedG729L2.Lengt h * 2);
for (int i = 0; i < 160; i++)
{
byte wByte = inbound[i];
bw.Write(wByte);
}
}
The decode function is declared as
[DllImport("decoder.dll", CallingConvention = CallingConvention.StdCall) ]
public static extern IntPtr decode([MarshalAs(Unmanage dType.LPAr ray, SizeConst = 10)]byte[] bArray);
The function in c++ looks like
extern "C" __declspec(dllexport) short * __stdcall decode(unsigned char serial[L_FRAME_COMPRESSED] )
{
int bfi=0;
short * retval = new short[80];
va_g729a_decoder(serial, retval, bfi);
return retval;
}
Any help on this one would be appreciated
Thanks,
Erik
I have an application that accepts audio data every 20ms. I decode the data and write it to disk. The problem is that I am getting corrupt data when I include some lines of code. Below will explain what I mean. Ultimately what I want to do is decode both inbound and outbound streams and mix them before writing. The trouble is as soon as I try and decode the ourbound stream something gets screwed.
See comments below:
byte[] InboundG729L1 = new byte[10], InboundG729L2 = new byte[10];
byte[] OutboundG729L1 = new byte[10], OutboundG729L2 = new byte[10];
short[] InboundDecodedG729L1 = new short[80], InboundDecodedG729L2 = new short[80];
short[] OutboundDecodedG729L1 = new short[80], OutboundDecodedG729L2 = new short[80];
short[] inbound = new short[160], outbound = new short[160];
short result = 0;
byte retval;
//Copy both halves of the RTP data into seperate arrays
Buffer.BlockCopy(inboundRT
Buffer.BlockCopy(inboundRT
Buffer.BlockCopy(outboundR
Buffer.BlockCopy(outboundR
//Decode first half of data
IntPtr p = Global.decode(InboundG729L
Marshal.Copy(p, InboundDecodedG729L1, 0, 80);
Global.freemem(p);
//Decode second half of data
p = Global.decode(InboundG729L
Marshal.Copy(p, InboundDecodedG729L2, 0, 80);
Global.freemem(p);
//****** If I uncomment the following 3 lines the data comes out corrupted. It is fine as long as they remain commented
//****** As you can see the 3 lines shouldn;t have any effect on what I am writing to disk.
//****** Ultimately I want to use the decoded output from below to mix both streams together.
//p = Global.decode(OutboundG729
//Marshal.Copy(p, OutboundDecodedG729L1, 0, 80);
//Global.freemem(p);
//Copy both arrays of decoded data into one array ready to write to disk
Buffer.BlockCopy(InboundDe
Buffer.BlockCopy(InboundDe
for (int i = 0; i < 160; i++)
{
byte wByte = inbound[i];
bw.Write(wByte);
}
}
The decode function is declared as
[DllImport("decoder.dll", CallingConvention = CallingConvention.StdCall)
public static extern IntPtr decode([MarshalAs(Unmanage
The function in c++ looks like
extern "C" __declspec(dllexport) short * __stdcall decode(unsigned char serial[L_FRAME_COMPRESSED]
{
int bfi=0;
short * retval = new short[80];
va_g729a_decoder(serial, retval, bfi);
return retval;
}
Any help on this one would be appreciated
Thanks,
Erik
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ups, you are right. I was looking at the numbers only :D my bad.
I'm not into sound and otehr stuff like that, but the memory the pointer is pointing to was allocated and filled, right? because if it wasn't filled then it is the reason for the bad data resulted.
I am thinking that one way to check is to save that memory data (outbound) to disk and see if it's ok. then, in another application that you will only use for debugging :), decode that file content and see if it decodes ok.
that's what I can think of for the moment. I'll get back to you if needed in the morning.
cheers
I'm not into sound and otehr stuff like that, but the memory the pointer is pointing to was allocated and filled, right? because if it wasn't filled then it is the reason for the bad data resulted.
I am thinking that one way to check is to save that memory data (outbound) to disk and see if it's ok. then, in another application that you will only use for debugging :), decode that file content and see if it decodes ok.
that's what I can think of for the moment. I'll get back to you if needed in the morning.
cheers
ASKER
Hi,
OK mate, thanks again. I will have another play around and let you know what I come up with :-)
cheers,
Erik
OK mate, thanks again. I will have another play around and let you know what I come up with :-)
cheers,
Erik
ok. and don't forget to make sure that indeed you have valid data in the OutboundG729L1 ;)
ASKER
Ok. All data being returned looks to be valid. I saved the inbound stream to disk and that was fine. I saved the outbound stream to disk and that was fine also. But if I decode both streams and then do nothing more than save one of the streams to disk I get corruption. I compared the results of the two files and interestingly it seems that the first iteration is fine. IE the first 160 bytes is the same in both files after that it gets corrupted. BTW, the corruption isn't that bad that I can;t make out the audio. It just sounds very tinny and echoy?
I just can;t figure this out. It is driving me crazy.
Is there a workaround you can think of? Another way of calling the DLL perhaps?
cheers,
Erik
I just can;t figure this out. It is driving me crazy.
Is there a workaround you can think of? Another way of calling the DLL perhaps?
cheers,
Erik
well ... the dll calling looks ok.
what I am thinking now is that maybe the outboubd is not encoded with the same algorithm or the same way as the inbound. are you sure that they are encoded the same way?
also, is the inboud supposed to be the same as the outbound?
also, is one of the inboud/outbound data encoded/decoded depending on the other? meaning that for example outbound depends on inboud or viceversa.
also, just so that I understand the process: what is inboud and what is outbound? like, inboud is comming from a device and outbound is going to the sound card or how am I suppose to relate those 2?
thanks
what I am thinking now is that maybe the outboubd is not encoded with the same algorithm or the same way as the inbound. are you sure that they are encoded the same way?
also, is the inboud supposed to be the same as the outbound?
also, is one of the inboud/outbound data encoded/decoded depending on the other? meaning that for example outbound depends on inboud or viceversa.
also, just so that I understand the process: what is inboud and what is outbound? like, inboud is comming from a device and outbound is going to the sound card or how am I suppose to relate those 2?
thanks
ASKER
Hi,
Outbound and Inbound are both processed identically. What doesn;t make sense is that for the moment I am not doing anything with outbound. Merely the process of passing it to the dll and decoding it is enough to make the inbound object corrupt?
inbound object is an inbound rtp stream and outbound is the ourbound rtp stream from an IP phone. For some reason decoding the outbound object is somehow corrupting the inbound object even though they are totally seperate?
thanks again for your help,
Erik
Outbound and Inbound are both processed identically. What doesn;t make sense is that for the moment I am not doing anything with outbound. Merely the process of passing it to the dll and decoding it is enough to make the inbound object corrupt?
inbound object is an inbound rtp stream and outbound is the ourbound rtp stream from an IP phone. For some reason decoding the outbound object is somehow corrupting the inbound object even though they are totally seperate?
thanks again for your help,
Erik
I don't know how the whole thing is working, but I'm just thinking: is it possible that whn reading the outboud, the "cursor" of the inboud is progressing? what I am thinking about is that reading the outbound has the same effect as reading from a file: something gets changed that affects the input.
try this:
- if you save the outbound to a file (meaning that it is processed), does the inbound get corrupted just like in the case you decode the outbound? if so, my guessing might be correct.
if not, then try this:
- copy the outbound data not to file but to another memory location, and decode that memory location. is the inbound still getting corrupted? if not, then again my guessing might be correct, if yes, considering the case in which we are, I am lost :)
but before all that, I just took another look over the code and have a few issues understanding the requirements:
wasn't the following block of code
//Copy both arrays of decoded data into one array ready to write to disk
Buffer.BlockCopy(InboundDe codedG729L 1, 0, inbound, 0, InboundDecodedG729L1.Lengt h * 2); //Multiply by 2 because it is a byte offset and we are dealing with 16bits
Buffer.BlockCopy(InboundDe codedG729L 2, 0, inbound, 160, InboundDecodedG729L2.Lengt h * 2);
actually be:
//Copy both arrays of decoded data into one array ready to write to disk
Buffer.BlockCopy(InboundDe codedG729L 1, 0, inbound, 0, InboundDecodedG729L1.Lengt h * 2); //Multiply by 2 because it is a byte offset and we are dealing with 16bits
Buffer.BlockCopy(InboundDe codedG729L 2, 0, inbound, InboundDecodedG729L1.Lengt h * 2, InboundDecodedG729L2.Lengt h * 2);
then I'm guesing there might also be some kind of issues with the outbound since the outbound is 80 before decoding and not 10 as the inbound, and maybe you have done some mistakes when copy-pasting :) just a possibility
so you should get over the code and make sure that everything is correct ;)
cheers
try this:
- if you save the outbound to a file (meaning that it is processed), does the inbound get corrupted just like in the case you decode the outbound? if so, my guessing might be correct.
if not, then try this:
- copy the outbound data not to file but to another memory location, and decode that memory location. is the inbound still getting corrupted? if not, then again my guessing might be correct, if yes, considering the case in which we are, I am lost :)
but before all that, I just took another look over the code and have a few issues understanding the requirements:
wasn't the following block of code
//Copy both arrays of decoded data into one array ready to write to disk
Buffer.BlockCopy(InboundDe
Buffer.BlockCopy(InboundDe
actually be:
//Copy both arrays of decoded data into one array ready to write to disk
Buffer.BlockCopy(InboundDe
Buffer.BlockCopy(InboundDe
then I'm guesing there might also be some kind of issues with the outbound since the outbound is 80 before decoding and not 10 as the inbound, and maybe you have done some mistakes when copy-pasting :) just a possibility
so you should get over the code and make sure that everything is correct ;)
cheers
ASKER
Hi,
Tried all sorts of things. In the end I found a workaround by simply creating a second C++ DLL and then used that for the inbound. Must have something to do with initialising the decode or something.
Anyway thanks for all your help. Full points.
Tried all sorts of things. In the end I found a workaround by simply creating a second C++ DLL and then used that for the inbound. Must have something to do with initialising the decode or something.
Anyway thanks for all your help. Full points.
weird indeed :)
that possibility didn't even occure to me... hm.. have to open my eyes more widely next time :)
that possibility didn't even occure to me... hm.. have to open my eyes more widely next time :)
ASKER
Thanks for the response. I have checked the timings and the whole process is around 2ms and it is all in a single thread.
Also, not sure what you mean by decoding inboundg729L1 twice? I first decode InboundG729L1, then decode InboundG729L2. The commented lines decode OutboundG729L1, not InboundG729L1?
Could it be a pointer issue of some king courupting memory?
Many thanks,
Erik