2
\$\begingroup\$

I have a simple task as part of a larger autocorrelation DSP system - to convert from signed 16-bit integer audio samples to floating-point. This part is quite self-contained:

#include <cblas.h>

typedef int16_t sample_t;

void consume(const sample_t *samples, int N, int rate)
{
    float *input = calloc(N, sizeof(float)),
         *output = calloc(N, sizeof(float));
    assert(input);
    assert(output);
    
    for (int i = 0; i < N; i++)
        input[i] = (float)samples[i];

    // BLAS processing of 'input'

    for (int i = 0; i < N; i++)
    {
        output[i] = cblas_sdot(  // Standard CBLAS call
            N-i,     // N
            input,   // X
            1,       // incX
            input+i, // Y
            1        // incY
        );
    }
}

Due to external constraints - the hardware only supports S16_LE samples - ALSA cannot do this conversion for me, nor can cblas accept integer types; so I'm stuck doing this myself. I've not found anything in gsl or cblas that runs vectorized type conversion.

I'm also not in love with having to loop over a level-1 dot product, but I've not been able to find a good way in BLAS to represent a single level-2 (matrix-vector) multiplication where the matrix is just a heavily-aliased single vector.

Is there a better way to do this?

\$\endgroup\$
4
  • \$\begingroup\$ What does the function cblas_sdot() do? Do floating point errors matter input+i? Note: the first question is about this question being on-topic for CR. \$\endgroup\$
    – pacmaninbw
    Oct 13 '20 at 13:48
  • \$\begingroup\$ cblas_sdot is a standard method of the CBLAS library. If you think it would improve clarity, I can include the header file statement and call this out in the description. \$\endgroup\$
    – Reinderien
    Oct 13 '20 at 13:51
  • 1
    \$\begingroup\$ @pacmaninbw floating-point errors don't matter all that much, though the addition you indicated is pointer addition, not floating-point addition. \$\endgroup\$
    – Reinderien
    Oct 13 '20 at 13:52
  • \$\begingroup\$ Yes include the header file statement and call this out in the description. I don't see where rate is used in the function. \$\endgroup\$
    – pacmaninbw
    Oct 13 '20 at 13:52
2
\$\begingroup\$
  1. If this code goes into production then the asserts for the success of calloc() will be optimized out of the code if the code is optimized. Prefer if statements with calls to fprintf(stderr,.
  2. The parameter rate is never used, this can lead to maintenance errors in the future.
  3. For maintenance reasons the ability of someone else to understand the code I would suggest using &input[i] rather than input+ in the function call.
\$\endgroup\$
6
  • \$\begingroup\$ What's the mechanism by which assert gets dropped? \$\endgroup\$
    – Reinderien
    Oct 13 '20 at 14:08
  • \$\begingroup\$ Asserts are implemented as macros and are assumed to be debug tools. The macros go to blank code if the the debug flag isn't used. \$\endgroup\$
    – pacmaninbw
    Oct 13 '20 at 14:10
  • \$\begingroup\$ For the gcc tool chain, what is the debug flag? Just DEBUG? \$\endgroup\$
    – Reinderien
    Oct 13 '20 at 14:12
  • \$\begingroup\$ See en.cppreference.com/w/cpp/error/assert \$\endgroup\$
    – pacmaninbw
    Oct 13 '20 at 14:12
  • \$\begingroup\$ So it's not a debug flag; it's a non-debug flag - NDEBUG. \$\endgroup\$
    – Reinderien
    Oct 13 '20 at 14:16

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.