October 19, 2021, 10:02:51

Author Topic: Using a void pointer?  (Read 654 times)

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 363
    • Midimaster Music Education Software
Using a void pointer?
« on: June 25, 2021, 08:58:47 »
I tried to reduce three of my C-glue-functions into one. If I could use void-pointers I could use the same same function for the audio formats u8, s16, s32 ans f32.

So I replaced the fix Float-Pointers to universal Void-Pointer and depending on the given format I try o cast them into the necessary type:

before:
Code: [Select]
//one pass decoding 32bit float:
int MM_Decode32f(float *TSampleRAM){
....
float* pAudioData;
int result = ma_decode_file(...., &pAudioData);
....
for (i=0; i<100; i++){
TSampleRAM[i] =  pAudioData[i];
}
}

after:
Code: [Select]
//one pass decoding all formats:
int MM_Decode( void* TSampleRAM, int format){
...
void* pAudioData;
switch (format) {
....
case ma_format_f32:
TSampleRAM = (float*) TSampleRAM;
pAudioData = (float*) pAudioData;
break;
}
int result = ma_decode_file(...., &pAudioData);
...
for (i=0; i<100; i++){
TSampleRAM[i] =  pAudioData[i];
}
}

But now I get the Error Message:
Code: [Select]
C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c: In function 'MM_Decode':
C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c:270:17:
error: invalid use of void expression
   TSampleRAM[i] =  pAudioData[i];
                 ^
Build Error: failed to compile (1) C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c
Process complete

What do I forget?
« Last Edit: June 25, 2021, 09:05:41 by Midimaster »
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

Offline Steve Elliott

  • Hero Member
  • *****
  • Posts: 3235
  • elgol
Re: Using a void pointer?
« Reply #1 on: June 25, 2021, 10:10:36 »
Code: [Select]
Perhaps you need to de-reference the pointer and typecast too - but use the address of (&TSampleRAM) ?

TSampleRAM = *((float*) &TSampleRAM));
Windows 10 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
MacOS Big Sur 64-bit, 8Gb RAM, Intel i5 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB
Linux Mint 19.3 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
Raspberry pi 3, pi 4, pi 400, BBC B, C64, ZX Spectrum

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 363
    • Midimaster Music Education Software
Re: Using a void pointer?
« Reply #2 on: June 25, 2021, 11:51:14 »
wow! that looks complicate...

C is still not "my world"

Thank you steve. I will try it out immediately.
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 363
    • Midimaster Music Education Software
Re: Using a void pointer?
« Reply #3 on: June 25, 2021, 15:43:40 »
It looks like your's is no solution. I corrected the brackets. (was one to much):
Code: [Select]
int MM_Decode( void* TSampleRAM, int format){
...
TSampleRAM = *((float*) &TSampleRAM);


 but already this gives a new error message:
Code: [Select]
C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c: In function 'MM_Decode':
C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c:246:13:
error: incompatible types when assigning to type 'void *' from type 'float'

  TSampleRAM = *((float*) &TSampleRAM);
             ^


I tried a new approach:

This would work:
Code: [Select]
int MM_Decode( void* TSampleRAM, int format){
...
float* TSampleRAM_II;
TSampleRAM_II = (float *) TSampleRAM;
...
for (i=0; i<(frameCount*audioConfig.channels); i++){
TSampleRAM_II[i] =  1;
}

but when I try this inside the switch, it again does not compile:
Code: [Select]
int MM_Decode( void* TSampleRAM, int format){
...
switch (format) {
case ma_format_f32:
float* TSampleRAM_II;
TSampleRAM_II = (float *) TSampleRAM;
break;
}
...
for (i=0; i<(frameCount*audioConfig.channels); i++){
TSampleRAM_II[i] =  1;
}

now the error message is:
Code: [Select]
C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c: In function 'MM_Decode':
C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c:252:4: error: a label can only be part of a statement and a declaration is not a statement
    float* TSampleRAM_II;
    ^~~~~
C:/BlitzMaxNG/mod/mima.mod/miniaudio.mod/miniaudiowrapper.c:259:3: error: 'TSampleRAM_II' undeclared (first use in this function)
   TSampleRAM_II[i] =  1;
   ^~~~~~~~~~~~~
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

Offline Steve Elliott

  • Hero Member
  • *****
  • Posts: 3235
  • elgol
Re: Using a void pointer?
« Reply #4 on: June 25, 2021, 16:35:16 »
Ah, it was off the top of my head.  But I wouldn't use void pointers anyway, I would use C++ function overloading for this, so you have the same functions but the data type variance would mean C++ would select the correct version:

Code: [Select]
eg)

calc( int data ) {
...
}

calc( float data ) {
...
}

So now if you call calc with calc( 4.5 ); then C++ would know to use the floating point version.

But if you have large functions then I would suggest breaking your functions into smaller functions.  Getting crazy with pointers can lead to confusing bug ridden code.
Windows 10 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
MacOS Big Sur 64-bit, 8Gb RAM, Intel i5 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB
Linux Mint 19.3 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
Raspberry pi 3, pi 4, pi 400, BBC B, C64, ZX Spectrum

Offline col

  • Hero Member
  • *****
  • Posts: 598
Re: Using a void pointer?
« Reply #5 on: June 26, 2021, 19:23:12 »
Or template the function. One function, one code body, multiples types.
 :)

Oh yeah, you're using c, and not c++ so templates dont exist in c.
« Last Edit: June 26, 2021, 19:39:56 by col »

Offline Steve Elliott

  • Hero Member
  • *****
  • Posts: 3235
  • elgol
Re: Using a void pointer?
« Reply #6 on: June 26, 2021, 19:57:52 »
Aw C mainly, with a little C++ where absolutely necessary IMO Col lol.
Windows 10 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
MacOS Big Sur 64-bit, 8Gb RAM, Intel i5 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB
Linux Mint 19.3 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
Raspberry pi 3, pi 4, pi 400, BBC B, C64, ZX Spectrum

Offline col

  • Hero Member
  • *****
  • Posts: 598
Re: Using a void pointer?
« Reply #7 on: June 26, 2021, 20:12:15 »
but c doesn't have proper function overloading.

Offline Steve Elliott

  • Hero Member
  • *****
  • Posts: 3235
  • elgol
Re: Using a void pointer?
« Reply #8 on: June 26, 2021, 20:39:22 »
I know, the sweet spot for me is C with only a little C++.
Windows 10 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
MacOS Big Sur 64-bit, 8Gb RAM, Intel i5 2.3 Ghz, Intel Iris Plus Graphics 640 1536 MB
Linux Mint 19.3 64-bit, 16Gb RAM, Intel i5 3.2 GHz, Nvidia GeForce GTX 1050 (2Gb)
Raspberry pi 3, pi 4, pi 400, BBC B, C64, ZX Spectrum

Offline col

  • Hero Member
  • *****
  • Posts: 598
Re: Using a void pointer?
« Reply #9 on: June 26, 2021, 21:04:23 »
Each to their own then eh :)

With c++ you can simplify the process to something such as:
Code: [Select]
template<typename T>
void DoDecode(void* pSampleRAM, void* pAudioData, size_t SampleDataSize)
{
for (size_t i = 0; i < SampleDataSize; i++) {
static_cast<T*>(pSampleRAM)[i] =  static_cast<T*>(pAudioData)[i];
}
}

extern"C"
{
int MM_Decode(char* FileName, void *TSampleRAM, ma_format format){
//DEBUG_OUTPUT("MM DECODER ONE PASS 32bit \n");

ma_decoder_config audioConfig = ma_decoder_config_init(format, 0, 0);
ma_uint64 frameCount;
void* pAudioData;
int result = ma_decode_file(FileName, &audioConfig, &frameCount, &pAudioData);
   
size_t SampleDataSize = frameCount * audioConfig.channels;
switch(format) {
case ma_format_s16:
DoDecode<short>(TSampleRAM, pAudioData, SampleDataSize);
break;
case ma_format_f32:
DoDecode<float>(TSampleRAM, pAudioData, SampleDataSize);
break;
case ma_format_s32:
DoDecode<int>(TSampleRAM, pAudioData, SampleDataSize);
break;
default:
DEBUG_OUTPUT(__FILE__, __LINE__, " Unknown sample format.");
}
DEBUG_OUTPUT("------ \n");
return 1;
}
}
« Last Edit: June 26, 2021, 21:11:41 by col »

Offline Midimaster

  • Sr. Member
  • ****
  • Posts: 363
    • Midimaster Music Education Software
Re: Using a void pointer?
« Reply #10 on: June 26, 2021, 23:21:08 »
this all looks for me looks like better staying on my current version with 4 nearly same functions and differ the cases on the BlitzMax side. This approach is easy and stabil.
See my current project on PlayStore: 20Tracks-Audio-Player https://play.google.com/store/apps/details?id=midimaster.twentytrackd

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal