Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Writing flac tag (Read 4236 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Writing flac tag

Hi, I'd like to use VisualBasic to write tag data to flac files. But I don't know/can't fully understand the layout.
All I have is a Hex Editor to look at a file with/without tags and compare.
I read there is an 8k block where this data can be written without needing to change the file size or audio content.
It appears to start after the first chunk of metadata and consist of FIELDNAME=ddd  followed by XX then three zero bytes.
XX seems to be the size of the next field.
But I cannot find what the first and last bytes in the tag data should be, or how to calculate where it should start.
Maybe someone has already figured this out?  Any help appreciated.


Re: Writing flac tag

Reply #2
Wow, thanks, but that is just too advanced for me.  I can't begin to follow what Start = 0x40+0 means.
Is there anything else perhaps a little clearer?
I had partial success today and manged to write a couple of fields and Winamp would play the file. But other things went into Stream-Error.




Re: Writing flac tag

Reply #5
Thanks for the replies.
 I've read (many times) details at xiph.org but I'm not getting from it what I need to know. My goal is to write a new set of or edit the comment fields, The actual audio sections I accept are beyond me, and hopefully the comment fields are (somewhat) independent of them..
Those new links above are much better e.g the one showing structure and how the header is decoded, but only being able to guess what an unsigned integer of 32 bits is you'll see my difficulty.  The "vendor string" appears to end in a date as "yyyymmdd". From looking in Hex Editor  the next byte is the first in the comment header. I think.
But to to decipher Start = 0x40+0 they say
Each starting position (shortened to 'start' in the tables) is a hexadecimal byte position and a start bit within that byte, separated by a plus sign. Counts for these start at zero. For example, a feature starting at the 3rd bit of the 17th byte is referred to as starting at 0x10+2
Here's my take on this. 10 is decimal 16 and 2 is 2. You add 1 to each as they're zero based, becoming the 3rd bit of byte 17. But what is the "0x"? Most (all) examples appear to repeat it and it never changes. They do say "counts for these start at zero" but what does that mean. When is is not zero?

D.1.3. Signature and streaminfo gives an example for calculating the first audio frame as the first byte after the metadata block header + the length of the block, i.e., 8+34 = 42 or 0x2a
So I'm currently trying to figure out how those numbers are derived from that shown in the table.

Re: Writing flac tag

Reply #6
The 0x is the radix. It tells you that the number is in hexadecimal notation.

Anyway, it seems you might be better of using a library instead of doing it yourself. From a quick google search, I found this one, maybe it is useful? https://www.3delite.hu/Object%20Pascal%20Developer%20Resources/TagsLibrary.html
Music: sounds arranged such that they construct feelings.

Re: Writing flac tag

Reply #7
Many thanks for the suggestion, sounded quite feasible.
I downloaded it but when I ran it got Tags Library 1.0 Setup.exe is not a valid Win32 application.
Going back to DIY Is there anywhere I can go to find what I need to know? I am making progress but it's more sideways than forward.


Re: Writing flac tag

Reply #8
To manage the diy route you need to understand the very basics of programming notation and encoding. 0x denotes hexadecimal, a 32 bit integer is a whole number that takes up 32 bits aka 4 bytes, multi-byte integers are stored as little endian in the vorbis metadata block ( https://en.wikipedia.org/wiki/Endianness ), metadata header block integers are big endian 24 bit, utf-8 is a superset of ascii ( https://en.wikipedia.org/wiki/UTF-8 ). That should be the bare minimum.

If your goal is simply to edit tags and not interact with the rest of the file format, you don't need to understand binary as the tag spec works in bytes and we can work around the binary in metadata headers. All you'd need to do is find the vorbis metadata block by reading all metadata blocks, if it doesn't exist you'll have to create it, then edit as desired.

To find the vorbis block you'll need to iterate through all the metadata blocks. A metadata block has a header consisting of an identifier byte and the length of the block as a 24 bit big endian integer. The first byte of the vorbis block is either 0x04 if it's not the last metadata block in the file, or 0x84 if it is. The last metadata block always begins with 0x8, the rest always start with 0x0. If you have to create a vorbis block you need to ensure that the last header block and only the last header block has its identifier starting with 0x8.

This is probably very confusing, it's a rewording of the links which may make more or less sense, but all the information is there. If you can't figure it out from the links and this thread then I suggest not going the diy route for now.

Re: Writing flac tag

Reply #9
Much appreciated Cid42. Your plain english and specifics have helped no end with examples D.1.2. and D.1.3. in https://www.ietf.org/archive/id/draft-ietf-cellar-flac-12.html#name-vorbis-comment-2 and making some sense of it.
You say the last metadata block always begins with 0x8. 00001000.
D.1.3 shows 0x04+0 1 bit   0b1 last metadata block
Assuming 0b means binary and 1 is most significant bit then this is 0x80.  Not 0x8? A bit disconcerting as I've missed something here.
I do (now) understand the 3 bytes after this hold the block length in bid endian
As an intro and exercise I'm going to use an existing flac file and see if I can iterate through all the metadata blocks and correlate the correct first audio frame address.

And to confirm, the vorbis block is also a metadata block, but specifically for tag text?
Thanks.

Re: Writing flac tag

Reply #10
I said starts with 0x8, I should probably have written 0x8y as in 1000yyyy to be clearer (for binary yes you might see it written as 0b1000yyyy) where the value of yyyy depends on the type of block it is. Saying it like that was my way of trying to describe when the last_metadata_block_flag in the metadata block header should be set without you having to understand binary.

Iterating through the metadata blocks is a good exercise, and also necessary for what you want to accomplish.

The vorbis block is a metadata block, the metadata block for tags.

Re: Writing flac tag

Reply #11
I read the first 9000 bytes of a flac file into a byte array.
I could identify/confirm each part of the streaminfo up to the MD5 signature. Noting the sample rate and number of channels are -1.
Both my file and the example at D.1.2 show the next block starting at 0x2a. The example shows the audio bytes 0xfff8.
Mine was 0x03 (I was expecting an identifier byte of 0x0 or 0x08) followed by 0x0 0x01 0x0e. (Length 270)
Moving forward 270 bytes didn't get to a recongisable identifier byte or 24 bit length.
So I've made a mistake, I wonder where - and is there an annotated example of a second metadata block?
This would give me something to compare an actual flac to.  And are you/this forum ok with me asking all this ?

Re: Writing flac tag

Reply #12
Ask away, we can always ignore you if it's getting too much :P

The last_metadata_block flag and the block_type are contained in the same byte. The example has only a single metadata block, the streaminfo. As such the first byte of the streaminfo block header is 0x80, aka the last_metadata_block flag is set to 1 and the block_type is 0 for streaminfo. Once the metadata block with the last_metadata_block flag set to 1 is read, whichever type of metadata block it is, what follows is frame data.

0xfff8 is the start of the first frame.

Your next byte being 0x03 indicates the next metadata block is a seektable, and that it's also not the last metadata block. This means that your streaminfo block header had a first byte of 0x00, unlike the example which has 0x80.

Re: Writing flac tag

Reply #13
Good to see 3 make sense. But the 3 bytes after that ( 0x0 0x01 0x0e. (Length 270) I can't get past.

The 3 is at 0x2a. I'm adding 270 to 0x2a and the 4 bytes at 0x138 are 0x92 0x14 0x10 0x0
That can't be right, it isn't the last block (the vorbis block is still to come) and the size can't be 1314816.
If not 270 what is the correct value to move forwards by?
I also tried looking for 0x84 but the first instance was 0c3e74, even though vorbis block is (visually) the last one before the audio.

66 4C 61 43 00 00 00 22 10 00 10 00 00 05 80 00 2A 99 0A C4 42 F0 00 62
BD 1C 35 60 88 A7 D8 9D 27 F9 A0 8D 8C 26 F7 19 86 52 03 00 01 0E 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 06 B0 00
00 00 00 00 00 0E 4A C3 10 00 00 00 00 00 00 0D 70 00 00 00 00 00 00 1D
D5 A4 10 00 00 00 00 00 00 14 20 00 00 00 00 00 00 2C 9F 6E 10 00 00 00
00 00 00 1A E0 00 00 00 00 00 00 3C 1C 64 10 00 00 00 00 00 00 21 A0 00
00 00 00 00 00 4B 78 7D 10 00 00 00 00 00 00 28 50 00 00 00 00 00 00 5A
E1 4F 10 00 00 00 00 00 00 2F 10 00 00 00 00 00 00 69 D0 46 10 00 00 00
00 00 00 35 D0 00 00 00 00 00 00 79 49 04 10 00 00 00 00 00 00 3C 80 00
00 00 00 00 00 88 D5 D6 10 00 00 00 00 00 00 43 40 00 00 00 00 00 00 97
79 BB 10 00 00 00 00 00 00 4A 00 00 00 00 00 00 00 A6 3B BF 10 00 00 00
00 00 00 50 B0 00 00 00 00 00 00 B5 96 03 10 00 00 00 00 00 00 57 70 00
00 00 00 00 00 C5 4E CF 10 00 00 00 00 00 00 5E 30 00 00 00 00 00 00 D5
92 14 10 00 04 00 01 E3 20 00 00 00 72 65 66 65 72 65 6E 63 65 20 6C 69
62 46 4C 41 43 20 31 2E 32 2E 31 20 32 30 30 37 30 39 31 37 10 00 00 00
25 00 00 00 52 45 50 4C 41 59 47 41 49 4E 5F 52 45 46 45 52 45 4E 43 45
5F 4C 4F 55 44 4E 45 53 53 3D 38 39 2E 30 20 64 42 0F 00 00 00 54 49 54


Re: Writing flac tag

Reply #15
That did occur to me, I tried +4 and +8 and found both led nowhere. But I was wrong and I see now  4 is correct and the flow is
0x2a   00000011  3= seektable.   Len 270
0x13c   00000100 4 = vobis block  Len 483
0x323   10000001  129  Last vorb isblock.   Len 7939
0x222a   11111111  start of audio

The last char in vorbis block is s at 0ffset 0x322. It's followed by 0x81 0x00 0x1f 0x03
Then  zeros until 0x222a
Suddenly it makes sense. Now just to unravel the fields in the vobis block which I read are little endian.  There seems to be 4 bytes for the length. This is all becoming do-able.  Brilliant. Thank you.