Please help, with buffers and/or arrays.
| Tue, 2008-05-20 10:02 | |
|
Hi everybody, Im trying to measure some technics about audio reconstruction in symbian, and to do that Im sending 4 mixed packets of 4 samples of audio to a receiver to do the reconstruction. I mean, the sequence is: When I receive a packet, due to packet loss, I never know if Im going to receive another packet, so what I want is to immediately re order each one of the samples contained in the packet. Why? Because, I want a packet with "holes" to be able to reconstruct it. Thus I dont know if Im going to receive the packets in the same order Ive sent them. For example and for explaining purposes, assume that I work only with 3 packets of 2 samples each, and Ive received two packets: containing samples 1, 2, 4 and 6. I would like to put them in a structure that has the 1st and 2nd sample, then I want zeros (or what an empty buffer of audio should be) in 3rd position, then I want to copy sample number 4 Ive received, then zeros in 5th position, to finally copy sample 6. The structure has to be able to keep the information of what samples has arrived or I can use another structure to store this. I tried to do this with 2 TBuf8 (keeping the information of the samples received in one TBuf, and the audio information in another TBuf), but it didnt work 'cause it lets me write only at the end of the descriptor, this is, I have no problem to copying 1st and 2nd sample, but it crashes when I try to append the 4th sample at 4096*4 byte. I tried to put an empty buffer doing this: TBuf8<4096> aBuf; but it didnt work Then I think of an array, RArray is the simplest, but it accepts 640 bytes max for(TInt ii = 0; ii < 16; ii++) Im new at this forum, so I didnt use riched text to put code, but I tried to explain every step in detail. Any suggestion would help. |
|







Forum posts: 1151
You can write at any position in a TBuf, not only at the end.
just use operator[] to index into it.
You shouldn't use TBuf:s though for this, a better idea is RBufs, that always keep its storage on the heap.
TBuf:s this big, if declared as automatic stack variables will bust your stack very quickly.
RBuf8 iAudioBuffer; //a member in some class somewhere TBool iHasContent[16]; //flag field would be more efficient, but bools are easy.... [...] iAudioBuffer.CreateL(16*4096); // space for 16 samples; [...] void CMyClass::AddSample(TInt aSampleNo, const TDesC8& aBuffer) { TInt startindex = aSampleNo*4096; for(TInt i = 0; i < 4096; i++) { iAudioBuffer[startindex + i] = aBuffer[i]; } iHasContent[aSampleNo] = ETrue; }(Its possible to make a little bit more efficient using Mem::Copy instead of a for-loop)
Forum posts: 120
You can try increasing your stacksize by a significant amount using EPOCSTACKSIZE directive in your mmp file too.
Jupitar
Forum posts: 593
It's better to use RBuf8 or HBufC8 as alh suggested, and allocate your buffers dynamically. You can also use TDes::Insert to insert data in between existing data.
Forum posts: 6
Thanks to all of you guys.
The info provided by you give me good indications, and also helped me to understand more about this language.
But I have another problem/question
: I have an array of buffers (still working with TBuf8 to make sure the functionality is working, once functionality is ok I'll move all my buffers to Rbuf8 I promess
) and I want to do the assignment suggested by alh, so how can I do that?
I supposed that
TBuf8<4096> iAudioBuffer[16]; // the array in my .hiAudioBuffer[0-15][startindex + i] = aBuffer[i]; // here it crashes.
will do it, but it crashes with User -21 panic, telling me that some index is out of bounds.
[startindex + i] is 0 when it crashes, and the cause its not the arithmetic operation in the index of the array, because [0] (as a number) fails as well.
Im "completely" sure that
aBuffer[i]has info and its not the cause of the problem (I write to a console its value and aBuffer[0] is 0).I also know that iAudioBuffer[some sample between 1 to 16] has no data, because it hasn't been written by any method or function.
I thought that RBuf8 and TBuf8 could be distinct, but in this case, both has TUint8& operator[](TInt anIndex); inherited from TDes8.
Please help me...
Thanks once again
Forum posts: 1151
If you use a 2d-buffer, you don't have to offset with the "startindex", then you select what subbuffer to use by the first []
My example used a simple 1dimensional buffer, and then you need the "startindex" offset to jump to the next "subbuffer" within the buffer.
Similar to how you step between scanlines when accessing raw images...
Forum posts: 6
Mmmmm... Im a bit confused.
I can select what subbuffer to use by the first [], what I cant do is to write some bytes inside that buffer.
Let try in other words... I have an array of 16 TBuf8 objects, and I can access to them with iAudioBuffer[0], iAudioBuffer[1], ... iAudioBuffer[15], right?
Then what I need is to write the first, say, 5 bytes (==subbufers?) of one of this objects.
I thought that it has to be something like this:
( (iAudioBuffer[2]) [startindex] ) = myBlah;( (the Object) theOffset ) = myBlah;
But as I say it didnt work
Could you explain me how to do that?
Thanks a lot for ur time.
Forum posts: 1151
I think the problem is that this:
should be:
in your case.
My example used one single flat buffer, a single array, to store all audiodata.
Like this, here is place for 10 audiobuffers of 4096 bytes each:
__________
I called each of the logical buffers within the buffer for "subbuffers"
Then I used "startindex" to jump into the buffer, to write a part of it, lets say I want to write the 3rd audiobuffer.
I used startindex to step into it and after writing my buffer would look like
__X_______
Then I write the 5th buffer too and my buffer would look like
__X_X_____
Then write the 4th buffer and it would look like
__XXX_____
etc...
In your example code on the other hand, you do not use a flat buffer, you are using a 2-dimensional buffer, or as its also called "and array of arrays"
which could be diagrammed like this:
_
_
_
_
_
_
Then you use the first parantesis to select which "sub buffer", and you must use 0-based index to index into that sub-buffer.
I prefer the flat buffer approach, feels like I have more control, and I don't have to keep track of two indexes when using it.
And easier when scanning through all samples, since they all are guaranteed to be just after the previous sample in memory.
Forum posts: 6
Ive already "found" (just by following alh indications) a solution, replacing the assignment ( = ) by Append().
RBuf8 iAudioBuffer; //.hiAudioBuffer.CreateL(4096);
for(TInt i = 0; i < 4096; i++)
iAudioBuffer.Append(aBuffer[i]);
because:
iAudioBuffer[i] = aBuffer[i]; // crashes
It doesnt sound like I expected, but at least do what I wanted to do
Thank you so much.
PD: Definitely I'll replace my TBufs with RBufs,... to create objects dynamically, makes my life easier
Forum posts: 1151
Ah.. I think I know what the problem is now.
When you "Create" the buffer, you get a buffer with the maxlength of what you specify.
but Length is still set to 0, even though the memory for the whole array is allocated.
So before you can use = you have to do do:
The out-of-bounds check on [] is on the Length and not on the MaxLength....
Append ofcourse also works, but only if you add the buffers in order, and I thought a requirement was that they could come out-of-order.
Append is also a bit slower since each assignment also has to update the length of the descriptor.
Forum posts: 6
We were posting at the same time, LOL.
Thanks for the explanation, I got it perfectly... I just wanted to use my -already created- structure to store my buffers, because when I receive packets I stored them in an array, and the reconstruction is made after in other method that I thought that could use the same array.
Graphically, it would be like this:
iAudioBuffer[0] = XXXXXXXXXX // buffer of 10 samples received OKiAudioBuffer[1] = XXXXXXXXXX // buffer of 10 samples received OK
iAudioBuffer[2] = __________ // buffer lost <- this one I wanted to be able to reconstruct it sample by sample.
iAudioBuffer[3] = XXXXXXXXXX // buffer of 10 samples received OK
But its ok now, as my last post say, the method do what I wanted (although it sounds really bad
Thanks. Bye.
Forum posts: 6
Perfect man,...
Instead of
iAudioBuffer.CreateL(16*4096);iAudioBuffer.CreateMaxL(16*4096);
Alternatively,
iAudioBuffer.CreateL(16*4096);iAudioBuffer.SetMax();
Yep, trying to solve my problem, I create a method to sort them, losing some time, but doing it right...
Now I have more "tools" to do the reconstruction... I'll do it all over again, and in a few (7
) days I'll let you know how did it go.

PD: For other people reading this thread this link may help a lot
http://descriptors.blogspot.com/2005/06/33-can-you-give-example-of-how-to-use.html