Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast void to typedef (best practice)

Tags:

c++

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.

like image 989
Daniel P Avatar asked May 01 '13 15:05

Daniel P


1 Answers

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;
like image 131
rob mayoff Avatar answered Sep 30 '22 05:09

rob mayoff