Search code examples
calsapcmlibalsa

C: print an integer array as binary data


I want to record data from a microphone using alsa. This command:

int buf[4096];
memset(buf, 0, sizeof(buf));
snd_pcm_readi(capture_handle, buf, avail);

writes the microphone data into the integer buffer buf. ( I am not sure if the data that is written by ..._readi is even integer values, the documentation does'nt tell.)

But if I iterate through the buffer the numbers make no sense. As an example I get that buf[60] == -2,600,000,000 so its smaller than the minimum integer if integer is 32 bit. ( as a note this is not my code but I have to work on it). I want to get the binary values of this whole buffer array and make sense of the values and look up in which way they are saved into the buffer so I can recreate the soundwave with this data.


Solution

  • Better use an array of char to record raw data. But to answer your question:

    #include <limits.h>
    #include <stdio.h>
    
    void print_binary(int value)
    {
        unsigned mask = ~(~0u >> 1);  // set highest bit
    
        // iterate over all bits:
        for (size_t i = 0; i < sizeof(value) * CHAR_BIT; ++i) {
            putchar('0' + !!(value & mask));  // !! converts to bool 0 or 1
            mask >>= 1;  // shift to next lower bit
        }
    }
    
    int main(void)
    {
        int x = 9;
        print_binary(x);
        putchar('\n');
    }
    

    Output:

    00000000000000000000000000001001
    

    Shorter:

    #include <stdio.h>
    
    void print_binary(int value)
    {
        for (unsigned mask = ~(~0u >> 1); mask; mask >>= 1)
            putchar('0' + !!(value & mask));
    }
    


    PS: Just to clarify ~(~0u >> 1) (8 bits for simplicity):

    ~0u                  negate all bits                                    1111 1111
    ~0u >> 1         shift to right 1 bit and fill up with 0      0111 1111
    ~(~0u >> 1)    negate that                                         1000 0000