static size_t resample(StreamingSRC &src, const sample_t *in, size_t in_size, sample_t *out, size_t out_size) { size_t result_size = 0; size_t gone = 0; while (gone < in_size) { gone += src.fill(in + gone, in_size - gone); if (src.can_process()) { src.process(); if (result_size + src.size() > out_size) BOOST_FAIL("Not enough buffer size"); copy_samples(out, result_size, src.result(), 0, src.size()); result_size += src.size(); } } while (src.need_flushing()) { src.flush(); if (result_size + src.size() > out_size) BOOST_FAIL("Not enough buffer size"); copy_samples(out, result_size, src.result(), 0, src.size()); result_size += src.size(); } return result_size; }
void LineGen::gen_samples(samples_t samples, size_t n) { for (size_t i = 0; i < n; i++) samples[0][i] = t + i*k; t += n*k; for (int ch = 1; ch < spk.nch(); ch++) copy_samples(samples[ch], samples[0], n); }
void ToneGen::gen_samples(samples_t samples, size_t n) { double w = 2 * M_PI * double(freq) / double(spk.sample_rate); for (size_t i = 0; i < n; i++) samples[0][i] = sin(t + i*w); t += n*w; for (int ch = 1; ch < spk.nch(); ch++) copy_samples(samples[ch], samples[0], n); }
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { unsigned char *start=NULL; int y,len=-1, got_frame; AVFrame *frame = avcodec_alloc_frame(); if (!frame) return AVERROR(ENOMEM); while(len<minlen) { AVPacket pkt; int len2=maxlen; double pts; int x=ds_get_packet_pts(sh_audio->ds,&start, &pts); if(x<=0) { start = NULL; x = 0; ds_parse(sh_audio->ds, &start, &x, MP_NOPTS_VALUE, 0); if (x <= 0) break; // error } else { int in_size = x; int consumed = ds_parse(sh_audio->ds, &start, &x, pts, 0); sh_audio->ds->buffer_pos -= in_size - consumed; } av_init_packet(&pkt); pkt.data = start; pkt.size = x; if (pts != MP_NOPTS_VALUE) { sh_audio->pts = pts; sh_audio->pts_bytes = 0; } y=avcodec_decode_audio4(sh_audio->context, frame, &got_frame, &pkt); //printf("return:%d samples_out:%d bitstream_in:%d sample_sum:%d\n", y, len2, x, len); fflush(stdout); // LATM may need many packets to find mux info if (y == AVERROR(EAGAIN)) continue; if(y<0) { mp_msg(MSGT_DECAUDIO,MSGL_V,"lavc_audio: error\n"); break; } if(!sh_audio->parser && y<x) sh_audio->ds->buffer_pos+=y-x; // put back data (HACK!) if (!got_frame) continue; len2 = copy_samples(sh_audio->context, frame, buf, maxlen); if (len2 < 0) return len2; if(len2>0) { if (((AVCodecContext *)sh_audio->context)->channels >= 5) { int samplesize = av_get_bytes_per_sample(((AVCodecContext *) sh_audio->context)->sample_fmt); reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_LAVC_DEFAULT, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, ((AVCodecContext *)sh_audio->context)->channels, len2 / samplesize, samplesize); } //len=len2;break; if(len<0) len=len2; else len+=len2; buf+=len2; maxlen -= len2; sh_audio->pts_bytes += len2; } mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"Decoded %d -> %d \n",y,len2); if (setup_format(sh_audio, sh_audio->context)) break; } av_free(frame); return len; }
static GstFlowReturn vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet, GstClockTime timestamp, GstClockTime duration) { vorbis_sample_t **pcm; guint sample_count; GstBuffer *out; GstFlowReturn result; gint size; if (G_UNLIKELY (!vd->initialized)) goto not_initialized; /* normal data packet */ /* FIXME, we can skip decoding if the packet is outside of the * segment, this is however not very trivial as we need a previous * packet to decode the current one so we must be carefull not to * throw away too much. For now we decode everything and clip right * before pushing data. */ if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet))) goto could_not_read; if (G_UNLIKELY (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0)) goto not_accepted; /* assume all goes well here */ result = GST_FLOW_OK; /* count samples ready for reading */ if ((sample_count = vorbis_synthesis_pcmout (&vd->vd, NULL)) == 0) goto done; size = sample_count * vd->vi.channels * vd->width; GST_LOG_OBJECT (vd, "%d samples ready for reading, size %d", sample_count, size); /* alloc buffer for it */ result = gst_pad_alloc_buffer_and_set_caps (vd->srcpad, GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (vd->srcpad), &out); if (G_UNLIKELY (result != GST_FLOW_OK)) goto done; /* get samples ready for reading now, should be sample_count */ if (G_UNLIKELY ((vorbis_synthesis_pcmout (&vd->vd, &pcm)) != sample_count)) goto wrong_samples; /* copy samples in buffer */ copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm, sample_count, vd->vi.channels, vd->width); GST_LOG_OBJECT (vd, "setting output size to %d", size); GST_BUFFER_SIZE (out) = size; /* this should not overflow */ if (duration == -1) duration = sample_count * GST_SECOND / vd->vi.rate; vorbis_do_timestamps (vd, out, FALSE, timestamp, duration); if (vd->segment.rate >= 0.0) result = vorbis_dec_push_forward (vd, out); else result = vorbis_dec_push_reverse (vd, out); done: vorbis_synthesis_read (&vd->vd, sample_count); return result; /* ERRORS */ not_initialized: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("no header sent yet")); return GST_FLOW_ERROR; } could_not_read: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("couldn't read data packet")); return GST_FLOW_ERROR; } not_accepted: { GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("vorbis decoder did not accept data packet")); return GST_FLOW_ERROR; } wrong_samples: { gst_buffer_unref (out); GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE, (NULL), ("vorbis decoder reported wrong number of samples")); return GST_FLOW_ERROR; } }