What would be the best practice to cast a void array to a typedef?
This is how I am currently doing it :
typedef struct {
int16_t left,right;
} SampleStereo16;
void *buffer[100000]; // data buffer
SampleStereo16* sample;
// insert something here that writes to the buffer
sample = (SampleStereo16*) buffer;
This seems to work fine but somehow I have the feeling there is a better way. I was also wondering if there is way to have the sample array and the buffer share the same memory (now they each use their own memory).
Here is the full code I am currently working on :
#include "fmod.h"
#include "fmod.hpp"
#include "fmod_errors.h"
#include "wincompat.h"
#include <stdio.h>
typedef struct {
int16_t left,right;
} SampleStereo16;
void ERRCHECK(FMOD_RESULT result)
{
if (result != FMOD_OK)
{
printf("\nFMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
if (result != FMOD_ERR_FILE_EOF)
exit(-1);
}
}
int main(int argc, char *argv[])
{
FMOD::System *system;
FMOD::Sound *sound;
FMOD_RESULT result;
unsigned int version;
int channels;
int bits;
unsigned int lenbytes; // length in bytes read
void *buffer[1000000]; // data buffer
unsigned int *read; // number of bytes actually read
unsigned int position; // offset in PCM samples
unsigned int samplesread; // number of PCM samples read
unsigned int samplesbuffer; //
unsigned int cueposition;
SampleStereo16* sample;
/*
Create a System object and initialize.
*/
result = FMOD::System_Create(&system);
ERRCHECK(result);
system->getVersion(&version);
result = system->getVersion(&version);
ERRCHECK(result);
if (version < FMOD_VERSION)
{
printf("Error! You are using an old version of FMOD %08x. This program requires %08x\n", version, FMOD_VERSION);
getch();
return 0;
}
result = system->setOutput(FMOD_OUTPUTTYPE_ALSA);
ERRCHECK(result);
result = system->init(32, FMOD_INIT_NORMAL, 0);
ERRCHECK(result);
result = system->createStream("/home/dpk/Dropbox/Music/Will Smith - Miami.mp3", FMOD_SOFTWARE, 0, &sound);
result = sound->getFormat(0, 0, &channels, &bits);
ERRCHECK(result);
printf("channels : %d bits : %d \n", channels, bits);
if (channels!=2 and bits!=16)
{
printf("File must be stereo (2 channels) 16 bits \n");
exit(-1);
}
lenbytes = sizeof(buffer);
samplesbuffer = lenbytes / channels / ( bits / 8 );
position = 0;
cueposition = 0;
do
{
result = sound->seekData(position);
ERRCHECK(result);
printf("Reading block : %u ",position);
result = sound->readData(&buffer, lenbytes, read);
ERRCHECK(result);
samplesread = *read / channels / ( bits / 8 );
sample = (SampleStereo16*) buffer;
printf("number of PCM samples read : %u \n", samplesread);
for(unsigned int i=0; i<samplesread; i++)
{
if (cueposition==0 && ( abs(sample[i].left)>500 || abs(sample[i].right)>500 ) )
{
cueposition = position+i;
printf("cue point : %u \n", cueposition);
}
}
position += lenbytes / channels / ( bits / 8 );
} while(samplesread==samplesbuffer);
printf("\nExit\n");
/*
Shut down
*/
result = sound->release();
ERRCHECK(result);
result = system->close();
ERRCHECK(result);
result = system->release();
ERRCHECK(result);
return 0;
}
I am also getting segmentation faults when increasing the buffer too much, but from what I have been able to find so far it seems to be a stack size limit.
Also feel free to comment on anything I am doing wrong, I just recently (last week) started C++ so I am pretty sure some things look bad in my code.
Your buffer
is an array of pointers to void
. That is unusual. Usually we declare a buffer as an array of char
or unsigned char
or uint8_t
or some other byte-sized type:
char buffer[100000]; // data buffer
Anyway, the “correct” C++-style cast is reinterpret_cast
:
sample = reinterpret_cast<SampleStereo16 *>(buffer);
On the other hand, you could just declare buffer
as an array of SampleStereo16
in the first place. Then you don't need a cast at all:
SampleStereo16 buffer[6250];
SampleStereo16 *sample;
sample = buffer;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With