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(inboundRTP.RTPPayload, 0, InboundG729L1, 0, 10);
            Buffer.BlockCopy(inboundRTP.RTPPayload, 10, InboundG729L2, 0, 10);
            Buffer.BlockCopy(outboundRTP.RTPPayload, 0, OutboundG729L1, 0, 10);
            Buffer.BlockCopy(outboundRTP.RTPPayload, 10, OutboundG729L2, 0, 10);
            //Decode first half of data
            IntPtr p = Global.decode(InboundG729L1);
            Marshal.Copy(p, InboundDecodedG729L1, 0, 80);

            //Decode second half of data
            p = Global.decode(InboundG729L2);
            Marshal.Copy(p, InboundDecodedG729L2, 0, 80);

//****** 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(OutboundG729L1);
            //Marshal.Copy(p, OutboundDecodedG729L1, 0, 80);
            //Copy both arrays of decoded data into one array ready to write to disk
            Buffer.BlockCopy(InboundDecodedG729L1, 0, inbound, 0, InboundDecodedG729L1.Length * 2); //Multiply by 2 because it is a byte offset and we are dealing with 16bits
            Buffer.BlockCopy(InboundDecodedG729L2, 0, inbound, 160, InboundDecodedG729L2.Length * 2);

            for (int i = 0; i < 160; i++)
                byte wByte = inbound[i];

The decode function is declared as

[DllImport("decoder.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr decode([MarshalAs(UnmanagedType.LPArray, 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
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

I am just guessing here, but I think it might be one of these:
- data comming in at 20ms but is processed in more than 20 ms
- concurency issue if you are using threads (also may include the above issue)

but I am looking at the code and just can't figure it out why you decode InboundG729L1 and then decode InboundG729L2 and then (the commented lines) decode InboundG729L1 again. that means that you decode InboundG729L1 twice, which is normal to produce data corruption. no?

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
erik_nodlandAuthor Commented:

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,

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.

Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

erik_nodlandAuthor Commented:

OK mate, thanks again. I will have another play around and let you know what I come up with :-)


ok. and don't forget to make sure that indeed you have valid data in the OutboundG729L1 ;)
erik_nodlandAuthor Commented:
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?


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?

erik_nodlandAuthor Commented:

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,

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(InboundDecodedG729L1, 0, inbound, 0, InboundDecodedG729L1.Length * 2); //Multiply by 2 because it is a byte offset and we are dealing with 16bits
            Buffer.BlockCopy(InboundDecodedG729L2, 0, inbound, 160, InboundDecodedG729L2.Length * 2);

actually be:

            //Copy both arrays of decoded data into one array ready to write to disk
            Buffer.BlockCopy(InboundDecodedG729L1, 0, inbound, 0, InboundDecodedG729L1.Length * 2); //Multiply by 2 because it is a byte offset and we are dealing with 16bits
            Buffer.BlockCopy(InboundDecodedG729L2, 0, inbound, InboundDecodedG729L1.Length * 2, InboundDecodedG729L2.Length * 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 ;)

erik_nodlandAuthor Commented:

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 :)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.