How do I get all the information regarding the header of an audio file? - header

How do I get all the information regarding the header of an audio file, so it can be displayed in a readable format like ASCII values?
The audio file maybe of any format, most preferably .wav format.
EDIT:- OS can be windows 8.1 or ubuntu. I actually have to understand all the properties of the file like whether it is mono or stereo, its encoding, etc. maybe specifically .wav file, i would say.
I have knowledge about the C++ language, so that would be better.

There is a very powerful command you can use in a bash script: sox.
To get all the info you need about a wav file, you just have to run:
soxi file.wav
and you'll get something like:
Input File : 'file.wav'
Channels : 1
Sample Rate : 8000
Precision : 16-bit
Duration : 00:02:08.40 = 1027236 samples ~ 9630.34 CDDA sectors
File Size : 2.05M
Bit Rate : 128k
Sample Encoding: 16-bit Signed Integer PCM
sox is available for Windows as well, although I have never used there.

You can use FFPROBE utility from FFMPEG: http://ffmpeg.org/
"ffprobe" gathers information from multimedia streams and prints it in human- and machine-readable fashion.
For example it can be used to check the format of the container used by a multimedia stream
and the format and type of each media stream contained in it.
Code
ffprobe -i <file_name>
ffprobe -i myfile.wav
Output will look something like this
Input #0, wav, from 'myfile.wav':
Duration: 00:04:16.88, bitrate: 16 kb/s
Stream #0:0: Audio: g729 ([131][0][0][0] / 0x0083), 8000 Hz, 2 channels, s16p, 16 kb/s
Output Explanation:
g729 is encoding type here.
16 kb/s is the bit-rate.
2 channels
Sample rate 8000 Hz
For detailed information
ffprobe -i <file_name> -show_streams

Related

How can I (or is it possible to) convert the AVC codec profile and level to the MIME codec definition?

In my use-case I have to provide codec specification within the HTML5 video source's MIME type. But even a type="video/mp4; codecs=avc1" is not detailed enough for Firefox. Firefox needs the extra detail of for example type="video/mp4; codecs=avc1.64001E". My problem is that I don't know where to get this 64001E part from.
The whole identification happens on server side. So far I was using ffprobe and that's perfectly supplies me JSON format output, like so:
ffprobe -select_streams v:0 -v info -of json -show_entries stream=codec_name,level,profile,width,height -i 1CE89B23-F9BD-43B9-805B-C49ACA9E5FFB_xxxxxxx.mp4
"streams": [
{
"codec_name": "h264",
"profile": "High",
"width": 1080,
"height": 1920,
"level": 50
}
]
}
I can get the profile and the level, but nothing like 64001E. In my local environment I also have mediainfo:
mediainfo 8038B652-106B-4FBB-BAD6-AF7E32913FDE_xxxxxxx.mp4
General
Complete name : 8038B652-106B-4FBB-BAD6-AF7E32913FDE_xxxxxxx.mp4
Format : MPEG-4
Format profile : Base Media
Codec ID : isom (isom/iso2/avc1/mp41)
File size : 1.18 MiB
Duration : 6 s 634 ms
Overall bit rate : 1 496 kb/s
Writing application : Lavf57.83.100
Video
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : High#L3
Format settings : CABAC / 5 Ref Frames
Format settings, CABAC : Yes
Format settings, Reference frames : 5 frames
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 6 s 634 ms
Bit rate : 1 396 kb/s
Width : 360 pixels
Height : 480 pixels
Display aspect ratio : 0.750
Frame rate mode : Constant
Frame rate : 30.000 FPS
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
Bits/(Pixel*Frame) : 0.269
Stream size : 1.10 MiB (93%)
Writing library : x264 core 152 r2854 e9a5903
Encoding settings : cabac=1 / ref=5 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=8 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=2 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=15 / lookahead_threads=2 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=50 / rc=crf / mbtree=1 / crf=17.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00
Codec configuration box : avcC
Audio
ID : 2
Format : AAC LC
Format/Info : Advanced Audio Codec Low Complexity
Codec ID : mp4a-40-2
Duration : 6 s 632 ms
Duration_LastFrame : -9 ms
Bit rate mode : Constant
Bit rate : 90.4 kb/s
Channel(s) : 1 channel
Channel layout : C
Sampling rate : 44.1 kHz
Frame rate : 43.066 FPS (1024 SPF)
Compression mode : Lossy
Stream size : 73.2 KiB (6%)
Default : Yes
Alternate group : 1
What we see here is that the AAC part has a longer Codec ID mp4a-40-2, but the video stream is still just avc1.
I'm looking at lists https://tools.woolyss.com/html5-canplaytype-tester/ and https://wiki.whatwg.org/wiki/Video_type_parameters and I think maybe there's a programmatic way to convert the codec profile + level to the code what the MIME type codec specification has.
In https://developer.mozilla.org/en-US/docs/Web/Media/Formats/codecs_parameter I see that "avc1.4d002a" means Main Profile, Level 4.2. Looking at the list I linked earlier I figured that the 6 hex digits can be broken down into groups of two. The last two is the level. In this latest example the Level is 4.2, we just have to remove the dot => it becomes 42, which is 2a hex. The other 4 hex digits are related to the profile as Main, High, etc and then Progressive, but I haven't found a definition yet, and I wonder if the ffprobe is able to output things like High 4:2:2 Intra Level or High Progressive Level. We'll see.
https://www.rfc-editor.org/rfc/rfc6381#page-12 has some examples, but I followed the links and still don't see any definitive list or anything.
The ITU-T H.264 specification Annex A lists 14 profiles. In those listings there's a profile_idc mentioned, which seems to be the decimal for the first two hex digits, for example High's profile_idc is 100 decimal, which is 64 hexa. Now we just need to figure out the middle two hexa digits. Preferably a GitHub repo source file would be great where these things are curated into a sane concise const literal array.
It is described in e.g. Mozilla link ("PPCCLL is six hexadecimal digits specifying the profile number (PP), constraint set flags (CC), and level (LL)"). If you don't find a tool fitting your needs, we could extend e.g. MediaInfo for that, let us know.
Note: the CC indicated in the list are the expected flags, not the ones really in the file, it should be OK 99.99% of the time but you can not be sure it is the real content. MediaInfo internally reads the flags but it does not export them for the moment.

perl gunzip to buffer and gunzip to file have different byte orders

I'm using Perl v5.22.1, Storable 2.53_01, and IO::Uncompress::Gunzip 2.068.
I want to use Perl to gunzip a Storable file in memory, without using an intermediate file.
I have a variable $zip_file = '/some/storable.gz' that points to this zipped file.
If I gunzip directly to a file, this works fine, and %root is correctly set to the Storable hash.
gunzip($zip_file, '/home/myusername/Programming/unzipped');
my %root = %{retrieve('/home/myusername/Programming/unzipped')};
However if I gunzip into memory like this:
my $file;
gunzip($zip_file, \$file);
my %root = %{thaw($file)};
I get the error
Storable binary image v56.115 more recent than I am (v2.10)`
so the Storable's magic number has been butchered: it should never be that high.
However, the strings in the unzipped buffer are still correct; the buffer starts with pst which is the correct Storable header. It only seems to be multi-byte variables like integers which are being broken.
Does this have something to do with byte ordering, such that writing to a file works one way while writing to a file buffer works in another? How can I gunzip to a buffer without it ruining my integers?
That's not related to unzip but to using retrieve vs. thaw. They both expect different input, i.e. thaw expect the output from freeze while retrieve expects the output from store.
This can be verified with a simple test:
$ perl -MStorable -e 'my $x = {}; store($x,q[file.store])'
$ perl -MStorable=freeze -e 'my $x = {}; print freeze($x)' > file.freeze
On my machine this gives 24 bytes for the file created by store and 20 bytes for freeze. If I remove the leading 4 bytes from file.store the file is equivalent to file.freeze, i.e. store just added a 4 byte header. Thus you might try to uncompress the file in memory, remove the leading 4 bytes and run thaw on the rest.

SCSI read(10) reads out weird values- USB pendrive

I am implementing USB as a host using OHCI to read the files stored in the Flashdrive. To read I implement the read(10) command in SCSI. The Logical Block address being the sector number. The following is an image of the command I send for read(10) to read LBA 0x0000-
http://i.imgur.com/ky4FHlm.png
I read 512bytes(size of one sector or 1 LBA)and the following is the output that i get for LBA 0x0000-
http://imgur.com/jL6OEjE
The bytes in the above image are not present any where on the pendrive, I checked that using HXD. Now, for testing I filled the pendrive to full capacity. If I read any other LBA, other than 0x0000, then I always get 512 bytes of 0x00.
Could anyone please tell me what the problem could be?
Am I supposed to execute some other command before I do a read(10) so that the USB sends me the right data maybe?
From my understanding I have put DPO, FUA and FUA_NV=0 and also RDPROTECT=2

How can I use the value of mp2t.af.pcr as a Tshark field?

I have a wireshark capture that contains an RTP multicast stream (plus some other incidental data).
Using a Tshark command like the following, I can produce a CSV of the RTP timestamp compared with the packet capture time:
tshark.exe -r "capture.pcap" -Eseparator=, -Tfields -e rtp.timestamp -e frame.time_epoch -d udp.port==5000,rtp
This decodes the UDP packets as RTP, and successfully prints out the two fields as expected.
Now, my question: The payload of the RTP stream is an MPEG2 Transport Stream, and I also want to print the PCR value (if there is one) alongside the packet and RTP timestamps.
In wireshark, I can see the PCR being decoded correctly, however using a command like the following:
tshark.exe -r "HBO HD CZ.pcap" -Eseparator=,-Tfields -e rtp.timestamp -e frame.time_epoch -e mp2t.af.pcr -d udp.port==5000,mp2t
...only prints out a "1" if there is a PCR oresent, not the actual value. I have also checked the .pcr_flag to confirm that these two are not exchanged, but still I see the same result.
The documentation seems to call mp2t.af.pcr a "Label", does this mean that Tshark is not able to use it as a field? Is there a way to generate a CSV with these values?
(What part of the documentation calls it a "Label"? That's a somewhat odd description of a named field.)
The problem is that the value that Wireshark displays after "base(XXX)*300 + ext(YYY)" is calculated and displayed, but the field itself isn't given an integral type and is instead given a type that doesn't have a value. Arguably, it should be an FT_UINT64 field and should be given a value, so that you can filter on it and can print the value in TShark.
Please file an enhancement request for this on the Wireshark Bugzilla.

MPEG-2 video encoding with ffmpeg API: bigger filesize than ffmpeg.exe

I am trying to encode a video from raw YUV to MPEG-2 using the ffmpeg API.
My problem is that the API-generated file is approx. 1.7 times bigger than the equivalent files generated by ffmpeg itself.
I use the quantization parameter (via qmin and qmax) instead of the bitrate.
The API-version is basically:
//...
pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
pCodecCtx->qmin = 3;
pCodecCtx->qmax = 3;
pCodecCtx->time_base.num = 1;
pCodecCtx->time_base.den = 30;
avcodec_open(pCodecCtx, avcodec_find_encoder(CODEC_ID_MPEG2VIDEO));
//...
while(/*...*/) {
avcodec_encode_video(pCodecCtx, pOutbuf, outbufSize, pPicture);
//..
}
//...
For ffmpeg itself, I use the command:
ffmpeg -s 352x288 -r 30 -i foreman_352x288.yuv -f mpeg2video -vcodec mpeg2video -r 30 -pix_fmt yuv420p -qmin 3 -qmax 3 foreman.m2v
Why does the API-generate file achieve a bitrate of 5212 kb/s and the file generated by ffmpeg for the same qp a bitrate of 3047 kb/s??
(Even more puzzling is that the smaller ffmpeg version has a slightly higher PSNR, 40.49 dB vs. 40.02 dB).
Are there any other relevant parameters that I missed? Does the ffmpeg actually respect the quantization parameter?
When using the ffmpeg API, the picture type (I-frame, P-frame, etc.) needs to be set manually for each frame. By default, ffmpeg will make every frame an I-frame.
The solution is to set the picture type before encoding a frame (here for a GOP size of 12):
//...
while(/*...*/) {
if(pCodecCtx->frame_number % 12)
pPicture->pict_type = AV_PICTURE_TYPE_P;
avcodec_encode_video(pCodecCtx, pOutbuf, outbufSize, pPicture);
//...
}
//...
Note that setting pCodecCtx->gop_size before the encoding does not help.