çizmek ben ses kodlarını ve ffmpeg kullanarak dalga biçimini çizmek çalışıyorum, ve giriş ses verileri AV_SAMPLE_FMT_S16P
olduğunu temelde ben öğretici here takip ediyorum ve ses libao ince oynuyor. Şimdi dalga formunu kodu çözülmüş verileri kullanarak çizmem gerekiyor, şu anda csv dosyasını ayırmak ve excel üzerinde çizim yapmak için sol ve sağ kanal yazıyorum. Ancak dalga biçimi, aynı ses klibi kullanılarak Audacity'de gösterilen dalga formundan farklı bir şeydir. Csv üzerine yazılan değeri analiz ettiğimde, değerlerin çoğu uint16_t
(65535) değerine yakındır, fakat diğer bazı düşük değerler vardır, ancak çoğunluğu yüksek tepe noktasıdır. İşte FFMPEG Ses kod çözme ve dalga biçimini
kaynak kodu
, Düzenconst char* input_filename="/home/user/Music/Clip.mp3";
av_register_all();
AVFormatContext* container=avformat_alloc_context();
if(avformat_open_input(&container,input_filename,NULL,NULL)<0){
endApp("Could not open file");
}
if(avformat_find_stream_info(container, NULL)<0){
endApp("Could not find file info");
}
av_dump_format(container,0,input_filename,false);
int stream_id=-1;
int i;
for(i=0;i<container->nb_streams;i++){
if(container->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
stream_id=i;
break;
}
}
if(stream_id==-1){
endApp("Could not find Audio Stream");
}
AVDictionary *metadata=container->metadata;
AVCodecContext *ctx=container->streams[stream_id]->codec;
AVCodec *codec=avcodec_find_decoder(ctx->codec_id);
if(codec==NULL){
endApp("cannot find codec!");
}
if(avcodec_open2(ctx,codec,NULL)<0){
endApp("Codec cannot be found");
}
AVPacket packet;
av_init_packet(&packet);
//AVFrame *frame=avcodec_alloc_frame();
AVFrame *frame=av_frame_alloc();
int buffer_size=AVCODEC_MAX_AUDIO_FRAME_SIZE+ FF_INPUT_BUFFER_PADDING_SIZE;
// MSVC can't do variable size allocations on stack, ohgodwhy
uint8_t *buffer = new uint8_t[buffer_size];
packet.data=buffer;
packet.size =buffer_size;
int frameFinished=0;
int plane_size;
ofstream fileCh1,fileCh2;
fileCh1.open ("ch1.csv");
fileCh2.open ("ch2.csv");
AVSampleFormat sfmt=ctx->sample_fmt;
while(av_read_frame(container,&packet)>=0)
{
if(packet.stream_index==stream_id){
int len=avcodec_decode_audio4(ctx,frame,&frameFinished,&packet);
int data_size = av_samples_get_buffer_size(&plane_size, ctx->channels,
frame->nb_samples,
ctx->sample_fmt, 1);
if(frameFinished){
int write_p=0;
// QTime t;
switch (sfmt){
case AV_SAMPLE_FMT_S16P:
for (int nb=0;nb<plane_size/sizeof(uint16_t);nb++){
for (int ch = 0; ch < ctx->channels; ch++) {
if(ch==0)
fileCh1 <<((uint16_t *) frame->extended_data[ch])[nb]<<"\n";
else if(ch==1)
fileCh2 <<((uint16_t *) frame->extended_data[ch])[nb]<<"\n";
}
}
break;
}
} else {
DBG("frame failed");
}
}
av_free_packet(&packet);
}
fileCh1.close();
fileCh2.close();
avcodec_close(ctx);
avformat_close_input(&container);
delete buffer;
return 0;
: Ben dalga görüntüsü OpenCV kullanarak çizmek iliştirilmesi
, burada 0-255 aralığına örnek değerini ölçekli ve değerini aldı 127, 0 (Y ekseni) olarak. Şimdi (x, örnek değer) ila (x, 127) her bir örnek çekme hattı için x = 1,2,3 ...
örnek değerler döküm hassasiyetini kaybedecek gibi görünüyor. Örnek değerini "printf" ile biçimlendirdiğinizde hangi çıktıyı alırsınız? – benardier
Değeri printf ("% u", (imzasız kısa) out [write_p]); '," cout << (imzasız kısa) out [write_p]; ',' cout << (int) gibi üç yöntemle bastırma [write_p]; 'bana aynı değerleri veriyor. Ancak bu değer, csv dosya çıktısından farklıdır. – Haris
Meraklı. Biçim 16 bit işaretli olduğunda neden uint16_t'ye yayınlanıyorsunuz? – jaket