Skip to content

Microphone raw data returns values larger than 14-bits #496

@microbit-carlos

Description

@microbit-carlos

Related issue:

But #377 is about the default DMA value (0x88) leaking into the rawSplitter data, and this one is about the ADC values from the rawSplitter being outside of the expected range 0 to 2^14.

Issue

The nRF52 ADC is configured to produce 14-bit values. These are stored in a signed in a 16-bit register, and assuming the range should be +/- 2^13, that'd be from -8192 to 8191.
When looking at the data coming from the rawSplitter we can see some values are not within this range.

Replicator

This example programme creates a DataSink connected to the rawSplitter, and simply checks the first 8K samples received via pull requests.

If the 16-bit data from the rawSplitter is larger than 2^14 it prints a message to serial.

Click here to view source code.

Built from codal-microbit-v2 commit 8256835, and the main branches from codal-core (a2f5051dc60f89276546517f1077e75659ae6741) and codal-nrf52 (1fbb7240290fe36a55c61378f5cdeb7640f3ec4a) at the time.

{
    "target": {
        "name": "codal-microbit-v2",
        "url": "https://github.com/lancaster-university/codal-microbit-v2",
        "branch": "master",
        "dev": true,
        "type": "git"
    },
    "config":{
        "MICROBIT_BLE_ENABLED" : 0,
        "MICROBIT_BLE_PAIRING_MODE": 0
    }
}
#include "MicroBit.h"

MicroBit uBit;

class DataSinkChecker : public DataSink {
public:
    SplitterChannel *upstream;
    uint16_t *dest;
    int dest_pos_ptr;
    size_t dest_max;

    DataSinkChecker(SplitterChannel *source) : upstream(source) { }
    virtual ~DataSinkChecker() { }

    void checkAsync() {
        if (this->upstream->getFormat() != DATASTREAM_FORMAT_16BIT_SIGNED) {
            uBit.serial.printf("upstream format '%d' invalid, expected signed 16 bit\n", this->upstream->getFormat());
            return;
        }
        upstream->connect(*this);
    }

    virtual int pullRequest() {
        ManagedBuffer buffer = this->upstream->pull();
        if (buffer.length() == 0) {
            uBit.serial.printf("No data received\n");
        }
        if (buffer.length() % 2 != 0) {
            uBit.serial.printf("Buffer with uneven bytes (%d).\n", buffer.length());
        }
        int16_t *pull_buf = (int16_t *)buffer.getBytes();
        for (int i = 0; i < buffer.length() / 2; i++) {
            if (pull_buf[i] >= (1 << 13) || pull_buf[i] < -(1 << 13)) {
                uBit.serial.printf("Sample >= 14b (signed): %d\n", pull_buf[i]);
            }
            // uBit.serial.printf("%d,%d\n", (int)(uint16_t)pull_buf[i], (int)(int16_t)pull_buf[i]);
        }

        return DEVICE_OK;
    }
};


int main() {
    uBit.init();

    uBit.serial.printf("\nMicrophone data capture Test\n");
    DataSinkChecker *micDataChecker = new DataSinkChecker(uBit.audio.rawSplitter->createChannel());
    micDataChecker->checkAsync();
    while (true) {
        uBit.sleep(10);
    }
}

And blowing on the microphone to saturate the signal we can see the values jumping quite easily.

This is with a micro:bit V2.00, which almost looks like it's within range, but 0 to 2^14, however loading the hex file in different micro:bit (more info below) shows a larger range:

Image
Microphone data capture Test
Sample >= 14b (signed): 8543
Sample >= 14b (signed): 9004
Sample >= 14b (signed): 9312
Sample >= 14b (signed): 9421
Sample >= 14b (signed): 9357
Sample >= 14b (signed): 9162
Sample >= 14b (signed): 8874
Sample >= 14b (signed): 8632
Sample >= 14b (signed): 8506
Sample >= 14b (signed): 8305
Sample >= 14b (signed): 8218
Sample >= 14b (signed): 8301
Sample >= 14b (signed): 8296
Sample >= 14b (signed): 8415
Sample >= 14b (signed): 8198
Sample >= 14b (signed): 8288
Sample >= 14b (signed): 8687
Sample >= 14b (signed): 10306
Sample >= 14b (signed): 9620
Sample >= 14b (signed): 8287
Sample >= 14b (signed): 9864
Sample >= 14b (signed): 10685
Sample >= 14b (signed): 10524
Sample >= 14b (signed): 9889
Sample >= 14b (signed): 9657
...

And this is a micro:bit V2.2x with the HongSound alternative mic:

Image
Microphone data capture Test
Sample >= 14b (signed): 9169
Sample >= 14b (signed): 15078
Sample >= 14b (signed): 10718
Sample >= 14b (signed): 11746
Sample >= 14b (signed): 11535
Sample >= 14b (signed): 13607
Sample >= 14b (signed): 13985
Sample >= 14b (signed): 10502
Sample >= 14b (signed): 8631
Sample >= 14b (signed): 14391
Sample >= 14b (signed): -11253
Sample >= 14b (signed): 16136
Sample >= 14b (signed): 8580
Sample >= 14b (signed): 10650
Sample >= 14b (signed): 10417
Sample >= 14b (signed): 13365
Sample >= 14b (signed): 9300
Sample >= 14b (signed): 15772
Sample >= 14b (signed): 8793
Sample >= 14b (signed): 8488
Sample >= 14b (signed): 15942
Sample >= 14b (signed): 16380
Sample >= 14b (signed): -15180
Sample >= 14b (signed): -13858
Sample >= 14b (signed): 13770
Sample >= 14b (signed): 16380
Sample >= 14b (signed): 16380
...

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions