5
\$\begingroup\$

I am writing a program in c++ to record audio.
Here are my structure and code snippet.

typedef struct _recorder {
    const uint32_t SAMPLE_RATE = 44100;
    const uint32_t FRAME_STEP = SAMPLE_RATE / 100;
    const uint32_t STEP_BUF_SIZE = sizeof(int16_t) * FRAME_STEP;
    int16_t *step_buf;

    const uint32_t RECORD_TIME = 10;
    const uint32_t NUM_SAMPLE = RECORD_TIME * SAMPLE_RATE;
    int16_t *total_buf;

    uint32_t sample_counter;
} recorder;

void recorder_init(recorder *r)
{
    r->step_buf = new int16_t[r->STEP_BUF_SIZE / sizeof(int16_t)];
    r->total_buf = new int16_t[r->NUM_SAMPLE];
}

void recorder_free(recorder *r)
{
    delete[] r->step_buf;
    delete[] r->total_buf;
}

void main(int argc, char *argv[])
{
    recorder rec;
    recorder_init(&rec);

    // Do something to record audio

    recorder_free(&rec);
}

Does using structures and functions make sense to you? Or should I use a class? Or there are better design patterns I can follow?

EDIT -------------------------
I add a further question of this post here.

\$\endgroup\$
  • \$\begingroup\$ You are assuming 16 bit samples, but in the real world, 24 bit hardware (and even 32 bit) are common. \$\endgroup\$ – Neil Oct 20 '17 at 14:52
13
\$\begingroup\$

This is very much C-style code: the only thing that qualifies it as C++ is the fact that you use new and delete[] rather than malloc() and free().

I don't see why RECORD_TIME should be a constant. I would expect it to be a constructor parameter. Or, use std::vector to store the samples, and you won't even have to worry about the array capacity, or even new and delete[].

The recorder class should be responsible for initializing sample_counter to zero, which you never did in your recorder_init(). In addition, I would expect there to be a method for appending a sample, and that method would automatically increment sample_counter. Again, though, if you used a std::vector, you wouldn't need such a complication, since the vector's size would serve that purpose.

\$\endgroup\$
4
\$\begingroup\$

There's not very much difference between structs and classes in C++. structs can have methods and protected and private data, for example.

But given what you've posted above, I think it makes more sense to make the above functions be methods of a class or struct. This allows you to use RAII, for example. The constructor and destructor would do what recorder_init() and recorder_free() do.

\$\endgroup\$
  • \$\begingroup\$ When you mention struct in C++, it's worthwhile to mention that you don't need typedef struct fakename { } correctname but can and should write struct correctname. This is important when you add member functions. \$\endgroup\$ – MSalters Oct 20 '17 at 12:53
  • \$\begingroup\$ I strongly dislike having to explicitly write struct before every use of the type, so personally prefer the older way of using a typedef or the newer using syntax. \$\endgroup\$ – user1118321 Oct 20 '17 at 17:17
  • 1
    \$\begingroup\$ So did the creators of C++, which is why you don't need the typedef in any version of C++. \$\endgroup\$ – MSalters Oct 20 '17 at 17:18
  • 1
    \$\begingroup\$ It's more than you suggest: C++ does not have structs. C++ only has the struct keyword, and struct Foo { … } is identical to class Foo { public: … }. \$\endgroup\$ – wchargin Oct 20 '17 at 18:47
  • 1
    \$\begingroup\$ @wchargin ... identical with the exception of default visibility - public vs private. \$\endgroup\$ – vaxquis Oct 20 '17 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.