| 429 | } |
| 430 | |
| 431 | int sp_conv_compute(sp_data * sp, sp_conv * p, SPFLOAT * in, SPFLOAT * out) |
| 432 | { |
| 433 | SPFLOAT *x, *rBuf; |
| 434 | int i, n, nSamples, rBufPos; |
| 435 | |
| 436 | nSamples = p->partSize; |
| 437 | rBuf = &(p->ringBuf[p->rbCnt * (nSamples << 1)]); |
| 438 | /* store input signal in buffer */ |
| 439 | rBuf[p->cnt] = *in; |
| 440 | /* copy output signals from buffer */ |
| 441 | *out = p->outBuffers[0][p->cnt]; |
| 442 | |
| 443 | /* is input buffer full ? */ |
| 444 | if (++p->cnt < nSamples) |
| 445 | { |
| 446 | return SP_OK; |
| 447 | } |
| 448 | /* reset buffer position */ |
| 449 | p->cnt = 0; |
| 450 | /* calculate FFT of input */ |
| 451 | for (i = nSamples; i < (nSamples << 1); i++) |
| 452 | { |
| 453 | /* Zero padding */ |
| 454 | rBuf[i] = 0.0; |
| 455 | } |
| 456 | sp_fftr(&p->fft, rBuf, (nSamples << 1)); |
| 457 | /* update ring buffer position */ |
| 458 | p->rbCnt++; |
| 459 | |
| 460 | if (p->rbCnt >= p->nPartitions) |
| 461 | { |
| 462 | p->rbCnt = 0; |
| 463 | } |
| 464 | |
| 465 | rBufPos = p->rbCnt * (nSamples << 1); |
| 466 | rBuf = &(p->ringBuf[rBufPos]); |
| 467 | /* PB: will only loop once since nChannels == 1*/ |
| 468 | for (n = 0; n < p->nChannels; n++) |
| 469 | { |
| 470 | /* multiply complex arrays */ |
| 471 | multiply_fft_buffers(p->tmpBuf, p->ringBuf, p->IR_Data[n], |
| 472 | nSamples, p->nPartitions, rBufPos); |
| 473 | /* inverse FFT */ |
| 474 | sp_ifftr(&p->fft, p->tmpBuf, (nSamples << 1)); |
| 475 | /* copy to output buffer, overlap with "tail" of previous block */ |
| 476 | x = &(p->outBuffers[n][0]); |
| 477 | for (i = 0; i < nSamples; i++) |
| 478 | { |
| 479 | x[i] = p->tmpBuf[i] + x[i + nSamples]; |
| 480 | x[i + nSamples] = p->tmpBuf[i + nSamples]; |
| 481 | } |
| 482 | } |
| 483 | return SP_OK; |
| 484 | } |
| 485 | |
| 486 | /* |
| 487 | FFT library |
no test coverage detected