static int fetch(extrapolater_t *self, unsigned nframes) { const pcm_sample_description_t *sfmt = pcm_get_format(self->src); buffer_t *bp = &self->buffer[self->nbuffer]; int rc = 0; if (realloc_buffer(bp, nframes * sfmt->bytes_per_frame) == 0) { rc = pcm_read_frames(self->src, bp->data, nframes); bp->count = rc > 0 ? rc : 0; } if (rc > 0) self->nbuffer ^= 1; return bp->count; }
static int read_frames(pcm_reader_t *reader, void *buffer, unsigned nframes) { pcm_float_converter_t *self = (pcm_float_converter_t *)reader; const pcm_sample_description_t *sfmt = pcm_get_format(self->src); nframes = pcm_read_frames(self->src, buffer, nframes); if (!(sfmt->sample_type & PCM_TYPE_FLOAT)) { int32_t *ip = buffer; float *op = buffer; unsigned i, count = nframes * sfmt->channels_per_frame; for (i = 0; i < count; ++i) op[i] = ip[i] / 2147483648.0f; } return nframes; }
static int encode(aacenc_param_ex_t *params, pcm_reader_t *reader, HANDLE_AACENCODER encoder, uint32_t frame_length, m4af_ctx_t *m4af) { int16_t *ibuf = 0, *ip; aacenc_frame_t obuf[2] = {{ 0 }}, *obp; unsigned flip = 0; int nread = 1; int rc = -1; int remaining, consumed; int frames_written = 0, encoded = 0; aacenc_progress_t progress = { 0 }; const pcm_sample_description_t *fmt = pcm_get_format(reader); ibuf = malloc(frame_length * fmt->bytes_per_frame); aacenc_progress_init(&progress, pcm_get_length(reader), fmt->sample_rate); for (;;) { /* * Since we delay the write, we cannot just exit loop when interrupted. * Instead, we regard it as EOF. */ if (g_interrupted) nread = 0; if (nread > 0) { if ((nread = pcm_read_frames(reader, ibuf, frame_length)) < 0) { fprintf(stderr, "ERROR: read failed\n"); goto END; } if (!params->silent) aacenc_progress_update(&progress, pcm_get_position(reader), fmt->sample_rate * 2); } ip = ibuf; remaining = nread; do { obp = &obuf[flip]; consumed = aac_encode_frame(encoder, fmt, ip, remaining, obp); if (consumed < 0) goto END; if (consumed == 0 && obp->size == 0) goto DONE; if (obp->size == 0) break; remaining -= consumed; ip += consumed * fmt->channels_per_frame; flip ^= 1; /* * As we pad 1 frame at beginning and ending by our extrapolator, * we want to drop them. * We delay output by 1 frame by double buffering, and discard * second frame and final frame from the encoder. * Since sbr_header is included in the first frame (in case of * SBR), we cannot discard first frame. So we pick second instead. */ ++encoded; if (encoded == 1 || encoded == 3) continue; obp = &obuf[flip]; if (write_sample(params->output_fp, m4af, obp) < 0) goto END; ++frames_written; } while (remaining > 0); } DONE: if (!params->silent) aacenc_progress_finish(&progress, pcm_get_position(reader)); rc = frames_written; END: if (ibuf) free(ibuf); if (obuf[0].data) free(obuf[0].data); if (obuf[1].data) free(obuf[1].data); return rc; }
static int read_frames(pcm_reader_t *reader, void *buffer, unsigned nframes) { limiter_t *self = (limiter_t *)reader; unsigned i, n, res, nch = self->format.channels_per_frame; size_t bytes = nframes * pcm_get_format(self->src)->bytes_per_frame; buffer_t *ibp = &self->buffers[nch]; float *obp = buffer; do { if (reserve_buffer(ibp, bytes, 1) < 0) return -1; res = pcm_read_frames(self->src, ibp->data, nframes); for (n = 0; n < nch; ++n) { float *ip = (float *)ibp->data, *x; buffer_t *bp = &self->buffers[n]; unsigned end, limit; if (reserve_buffer(bp, bp->count + res, sizeof(float)) < 0) return -1; x = bp->data; for (i = 0; i < res; ++i) x[bp->count++] = pcm_clip(ip[i * nch + n], -3.0, 3.0); limit = bp->count; if (limit > 0 && res > 0) { float last = x[limit - 1]; for (; limit > 0 && x[limit-1] * last > 0; --limit) ; } end = bp->head; while (end < limit) { unsigned start, peak_pos; float peak; for (peak_pos = end; peak_pos < limit; ++peak_pos) if (x[peak_pos] > 1.0f || x[peak_pos] < -1.0f) break; if (peak_pos == limit) break; start = peak_pos; peak = fabs(x[peak_pos]); while (start > bp->head && x[peak_pos] * x[start] >= 0.0f) --start; ++start; for (end = peak_pos + 1; end < limit; ++end) { float y; if (x[peak_pos] * x[end] < 0.0f) break; y = fabs(x[end]); if (y > peak) { peak = y; peak_pos = end; } } if (peak < 2.0f) { float a = (peak - 1.0f) / (peak * peak); if (x[peak_pos] > 0.0f) a = -a; for (i = start; i < end; ++i) x[i] = x[i] + a * x[i] * x[i]; } else { float u = peak, v = 1.0f; float a = (u - 2.0f * v) / (u * u * u); float b = (3.0f * v - 2.0f * u) / (u * u); if (x[peak_pos] < 0.0f) b = -b; for (i = start; i < end; ++i) x[i] = x[i] + b * x[i] * x[i] + a * x[i] * x[i] * x[i]; } } bp->head = limit; } res = nframes; for (n = 0; n < nch; ++n) if (self->buffers[n].head < res) res = self->buffers[n].head; for (i = 0; i < res; ++i) for (n = 0; n < nch; ++n) *obp++ = ((float *)self->buffers[n].data)[i]; if (res) { for (n = 0; n < nch; ++n) { buffer_t *bp = &self->buffers[n]; float *p = bp->data; memmove(p, p + res, (bp->count - res) * sizeof(float)); bp->count -= res; bp->head -= res; } } } while (res == 0 && self->buffers[0].count); self->position += res; return res; }