PDA

View Full Version : Accessing Byte values from a block of allocated memory...



WILL
04-02-2004, 05:16 AM
This should be a simple one.

ok lets say I've allocated some memory to store audio data in one of my objects using:

lets assume
var SamplePtr: Pointer;
SampleSize: Word;
and then
GetMem(SamplePtr, SampleSize);
then
ReadBlock(FileStream, SamplePtr^, SampleSize);

now...

How do I access this 8-bit audio data as if it were simply an array of Byte values? Or in some other similar way. Some code would be great.


I can't believe I've never done this in Win32 before.

Useless Hacker
04-02-2004, 08:16 AM
You could do this:
type
TByteArray = array[0..MaxInt] of Byte;

...

x := TByteArray(SamplePtr)[1];
I'm not too sure about the syntax there, but I know that this is possible.

Alimonster
04-02-2004, 09:17 AM
Useless Hacker is close with his suggestion, but you need another type:

type
TByteArray = array[0..MaxInt - 1] of Byte;
PByteArray = ^TByteArray; // and this
Use the above for your typecast in the code (x := PByteArray(SamplePtr)[some_index]). Note that the size of the initial array type is only really 'important' in two ways:

The compiler will complain if you access an element using a hard-coded number that's not in the range (e.g. TByteArray = array[0..1] of Byte, then you access MyArray[23] in code). That's a compile-time error.

Range checking (which I never remember to enable anyway) may trigger problems here, thinking you've overran the array boundaries (it doesn't know any better!).

The above two are the reasons why you usually use as big a declared array size as possible before using a pointer to it (you'll sometimes see "array[0..0]" types, then a pointer to them, in some code). Also, note that PByteArray is declared in SysUtils, so you don't necessarily have to redeclare the type unless you want to.

Alimonster
04-02-2004, 09:23 AM
Oh, and of course your code will be clearer if you use a variable to get rid of all the typecasts later, perhaps like this:

var
Blah: Pointer;
Another: PByteArray;
begin
Blah := DoSomethingToGetPointer;

Another := PByteArray(Blah); // here, the important bit

// now, it's clear all the way -- just like an array...
Another[0] := 1;
Another[1] := 23;
Another[2] := $FF;
end;

EDIT: And another thought. Are you sure you can't just use a dynamic array? It would make your life easier, you know! If you desperately need a pointer then it's not difficult to get one (just the address of element 0 after all).

holybyte
06-02-2004, 01:14 AM
(offtopic..)
Isn't newer Delphi supporting Pointer arithmetics ?? I know there are several tutorial for accessing a pixel in allocated mem for delphi3/4. They all use complicated pointer<->int conversion.



// freepascal code
VAR p &#58; pointer;
size &#58; longint;
pb &#58; ^BYTE;

Getmem&#40; p, size &#41;;
pb &#58;= p;
&#40;pb + number&#41;^&#58;=255;

WILL
06-02-2004, 02:45 AM
All: Thanks for your responses. I managed to get what I needed.

Alimonster: I am afraid I do. Dynamic arrays in class objects don't seem to keep well. I always run into problems. Also I will be feeding this data to OpenAL & DirectSound for playback so I'll need to keep it in a very compatable formatwith these.

ggs
08-02-2004, 04:42 PM
(offtopic..)
Isn't newer Delphi supporting Pointer arithmetics ?? I know there are several tutorial for accessing a pixel in allocated mem for delphi3/4. They all use complicated pointer<->int conversion.



// freepascal code
VAR p &#58; pointer;
size &#58; longint;
pb &#58; ^BYTE;

Getmem&#40; p, size &#41;;
pb &#58;= p;
&#40;pb + number&#41;^&#58;=255;


use:


VAR size &#58; longint;
p &#58; PByteArray;

Getmem&#40; p, size &#41;;
p&#91;number&#93; &#58;=255;

Much nicer code.

As far as I know even Turbo Pascal supported pointer arithmetic.


This code will walk over a raw byte a raw byte array backwards using pointer arithmetic. Inc() & dec() increase & decrease the pointer by the sizeof what the pointer points to(in this case a byte)


VAR
size &#58; longint;
p &#58; pointer;
pb &#58; ^Byte;

Getmem&#40; p, size &#41;;
pb &#58;= p;
inc&#40; pb, size div sizeof&#40;pb^&#41; &#41;;
while pb <> p do
begin
dec&#40;pb&#41;;
...
end;