/* Do window management once we have a complete window, including mangling
 * the current window. */
static int process_window(reddata_t data, int chan_num, int num_chans,
                          st_sample_t *obuf, int len) {
    int j;
    float* nextwindow;
    int use = min(len, WINDOWSIZE)-(WINDOWSIZE/2);
    chandata_t *chan = &(data->chandata[chan_num]);
    int first = (chan->lastwindow == NULL);

    nextwindow = (float*)calloc(WINDOWSIZE, sizeof(float));
    memcpy(nextwindow, chan->window+WINDOWSIZE/2,
           sizeof(float)*(WINDOWSIZE/2));

    reduce_noise(chan, chan->window, data->threshold);
        
    if (!first) {
        for (j = 0; j < use; j ++) {
            float s = chan->window[j] + chan->lastwindow[WINDOWSIZE/2 + j];
            if (s < -1 || s > 1) {
                float news;
                if (s > 1)
                    news = 1;
                else
                    news = -1;

                st_warn("noisered: Output clipped from %f to %f.\n",
                        s, news);
            }
            obuf[chan_num + num_chans * j] =
                ST_FLOAT_DWORD_TO_SAMPLE(s);
        }
        free(chan->lastwindow);
    } else {
        for (j = 0; j < use; j ++) {
            assert(chan->window[j] >= -1 && chan->window[j] <= 1);
            obuf[chan_num + num_chans * j] =
                ST_FLOAT_DWORD_TO_SAMPLE(chan->window[j]);
        }
    }
    chan->lastwindow = chan->window;
    chan->window = nextwindow;

    return use;
}
Пример #2
0
            u::bytes microphone::read_data()
            {
                REQUIRE(_d);
                if(!_d) return {};

                INVARIANT(_i);

                auto len = _i->bytesReady();
                if(len <= 0) return {};
                if(static_cast<size_t>(len) > MAX_SAMPLE_BYTES) len = MAX_SAMPLE_BYTES;

                u::bytes data;
                data.resize(len);

                auto l = _d->read(data.data(), len);
                if(l <= 0) return {};
                data.resize(l);

                //decimate and add to buffer
                decimate(data, _buffer, _channels, _skip);

                if(_buffer.size() < MIN_BUF_SIZE) return {};

                //once we have enough data, do noise reduction
                reduce_noise(_buffer, MIN_BUF_SIZE);

                //copy buffer to result
                u::bytes r(_buffer.begin(), _buffer.begin() + MIN_BUF_SIZE);

                //copy extra to front and resize. Probably a better idea to use a circular buf here.
                auto final_buf_size = _buffer.size() - MIN_BUF_SIZE;
                std::copy(_buffer.begin() + MIN_BUF_SIZE, _buffer.end(), _buffer.begin());
                _buffer.resize(final_buf_size);

                return r;
            }