Chris@1
|
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
Chris@1
|
2 <html>
|
Chris@1
|
3 <head>
|
Chris@1
|
4
|
Chris@1
|
5 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15"/>
|
Chris@1
|
6 <title>Ogg Vorbis Documentation</title>
|
Chris@1
|
7
|
Chris@1
|
8 <style type="text/css">
|
Chris@1
|
9 body {
|
Chris@1
|
10 margin: 0 18px 0 18px;
|
Chris@1
|
11 padding-bottom: 30px;
|
Chris@1
|
12 font-family: Verdana, Arial, Helvetica, sans-serif;
|
Chris@1
|
13 color: #333333;
|
Chris@1
|
14 font-size: .8em;
|
Chris@1
|
15 }
|
Chris@1
|
16
|
Chris@1
|
17 a {
|
Chris@1
|
18 color: #3366cc;
|
Chris@1
|
19 }
|
Chris@1
|
20
|
Chris@1
|
21 img {
|
Chris@1
|
22 border: 0;
|
Chris@1
|
23 }
|
Chris@1
|
24
|
Chris@1
|
25 #xiphlogo {
|
Chris@1
|
26 margin: 30px 0 16px 0;
|
Chris@1
|
27 }
|
Chris@1
|
28
|
Chris@1
|
29 #content p {
|
Chris@1
|
30 line-height: 1.4;
|
Chris@1
|
31 }
|
Chris@1
|
32
|
Chris@1
|
33 h1, h1 a, h2, h2 a, h3, h3 a {
|
Chris@1
|
34 font-weight: bold;
|
Chris@1
|
35 color: #ff9900;
|
Chris@1
|
36 margin: 1.3em 0 8px 0;
|
Chris@1
|
37 }
|
Chris@1
|
38
|
Chris@1
|
39 h1 {
|
Chris@1
|
40 font-size: 1.3em;
|
Chris@1
|
41 }
|
Chris@1
|
42
|
Chris@1
|
43 h2 {
|
Chris@1
|
44 font-size: 1.2em;
|
Chris@1
|
45 }
|
Chris@1
|
46
|
Chris@1
|
47 h3 {
|
Chris@1
|
48 font-size: 1.1em;
|
Chris@1
|
49 }
|
Chris@1
|
50
|
Chris@1
|
51 li {
|
Chris@1
|
52 line-height: 1.4;
|
Chris@1
|
53 }
|
Chris@1
|
54
|
Chris@1
|
55 #copyright {
|
Chris@1
|
56 margin-top: 30px;
|
Chris@1
|
57 line-height: 1.5em;
|
Chris@1
|
58 text-align: center;
|
Chris@1
|
59 font-size: .8em;
|
Chris@1
|
60 color: #888888;
|
Chris@1
|
61 clear: both;
|
Chris@1
|
62 }
|
Chris@1
|
63 </style>
|
Chris@1
|
64
|
Chris@1
|
65 </head>
|
Chris@1
|
66
|
Chris@1
|
67 <body>
|
Chris@1
|
68
|
Chris@1
|
69 <div id="xiphlogo">
|
Chris@1
|
70 <a href="http://www.xiph.org/"><img src="fish_xiph_org.png" alt="Fish Logo and Xiph.Org"/></a>
|
Chris@1
|
71 </div>
|
Chris@1
|
72
|
Chris@1
|
73 <h1>Ogg Vorbis I format specification: comment field and header specification</h1>
|
Chris@1
|
74
|
Chris@1
|
75 <h1>Overview</h1>
|
Chris@1
|
76
|
Chris@1
|
77 <p>The Vorbis text comment header is the second (of three) header
|
Chris@1
|
78 packets that begin a Vorbis bitstream. It is meant for short, text
|
Chris@1
|
79 comments, not arbitrary metadata; arbitrary metadata belongs in a
|
Chris@1
|
80 separate logical bitstream (usually an XML stream type) that provides
|
Chris@1
|
81 greater structure and machine parseability.</p>
|
Chris@1
|
82
|
Chris@1
|
83 <p>The comment field is meant to be used much like someone jotting a
|
Chris@1
|
84 quick note on the bottom of a CDR. It should be a little information to
|
Chris@1
|
85 remember the disc by and explain it to others; a short, to-the-point
|
Chris@1
|
86 text note that need not only be a couple words, but isn't going to be
|
Chris@1
|
87 more than a short paragraph. The essentials, in other words, whatever
|
Chris@1
|
88 they turn out to be, eg:</p>
|
Chris@1
|
89
|
Chris@1
|
90 <blockquote><p>
|
Chris@1
|
91 "Honest Bob and the Factory-to-Dealer-Incentives, _I'm Still Around_,
|
Chris@1
|
92 opening for Moxy Früvous, 1997"
|
Chris@1
|
93 </p></blockquote>
|
Chris@1
|
94
|
Chris@1
|
95 <h1>Comment encoding</h1>
|
Chris@1
|
96
|
Chris@1
|
97 <h2>Structure</h2>
|
Chris@1
|
98
|
Chris@1
|
99 <p>The comment header logically is a list of eight-bit-clean vectors; the
|
Chris@1
|
100 number of vectors is bounded to 2^32-1 and the length of each vector
|
Chris@1
|
101 is limited to 2^32-1 bytes. The vector length is encoded; the vector
|
Chris@1
|
102 contents themselves are not null terminated. In addition to the vector
|
Chris@1
|
103 list, there is a single vector for vendor name (also 8 bit clean,
|
Chris@1
|
104 length encoded in 32 bits). For example, the 1.0 release of libvorbis
|
Chris@1
|
105 set the vendor string to "Xiph.Org libVorbis I 20020717".</p>
|
Chris@1
|
106
|
Chris@1
|
107 <p>The comment header is decoded as follows:</p>
|
Chris@1
|
108
|
Chris@1
|
109 <pre>
|
Chris@1
|
110 1) [vendor_length] = read an unsigned integer of 32 bits
|
Chris@1
|
111 2) [vendor_string] = read a UTF-8 vector as [vendor_length] octets
|
Chris@1
|
112 3) [user_comment_list_length] = read an unsigned integer of 32 bits
|
Chris@1
|
113 4) iterate [user_comment_list_length] times {
|
Chris@1
|
114
|
Chris@1
|
115 5) [length] = read an unsigned integer of 32 bits
|
Chris@1
|
116 6) this iteration's user comment = read a UTF-8 vector as [length] octets
|
Chris@1
|
117
|
Chris@1
|
118 }
|
Chris@1
|
119
|
Chris@1
|
120 7) [framing_bit] = read a single bit as boolean
|
Chris@1
|
121 8) if ( [framing_bit] unset or end of packet ) then ERROR
|
Chris@1
|
122 9) done.
|
Chris@1
|
123 </pre>
|
Chris@1
|
124
|
Chris@1
|
125 <h2>Content vector format</h2>
|
Chris@1
|
126
|
Chris@1
|
127 <p>The comment vectors are structured similarly to a UNIX environment variable.
|
Chris@1
|
128 That is, comment fields consist of a field name and a corresponding value and
|
Chris@1
|
129 look like:</p>
|
Chris@1
|
130
|
Chris@1
|
131 <pre>
|
Chris@1
|
132 comment[0]="ARTIST=me";
|
Chris@1
|
133 comment[1]="TITLE=the sound of Vorbis";
|
Chris@1
|
134 </pre>
|
Chris@1
|
135
|
Chris@1
|
136 <ul>
|
Chris@1
|
137 <li>A case-insensitive field name that may consist of ASCII 0x20 through
|
Chris@1
|
138 0x7D, 0x3D ('=') excluded. ASCII 0x41 through 0x5A inclusive (A-Z) is
|
Chris@1
|
139 to be considered equivalent to ASCII 0x61 through 0x7A inclusive
|
Chris@1
|
140 (a-z).</li>
|
Chris@1
|
141 <li>The field name is immediately followed by ASCII 0x3D ('=');
|
Chris@1
|
142 this equals sign is used to terminate the field name.</li>
|
Chris@1
|
143 <li>0x3D is followed by the 8 bit clean UTF-8 encoded value of the
|
Chris@1
|
144 field contents to the end of the field.</li>
|
Chris@1
|
145 </ul>
|
Chris@1
|
146
|
Chris@1
|
147 <h3>Field names</h3>
|
Chris@1
|
148
|
Chris@1
|
149 <p>Below is a proposed, minimal list of standard field names with a
|
Chris@1
|
150 description of intended use. No single or group of field names is
|
Chris@1
|
151 mandatory; a comment header may contain one, all or none of the names
|
Chris@1
|
152 in this list.</p>
|
Chris@1
|
153
|
Chris@1
|
154 <dl>
|
Chris@1
|
155
|
Chris@1
|
156 <dt>TITLE</dt>
|
Chris@1
|
157 <dd>Track/Work name</dd>
|
Chris@1
|
158
|
Chris@1
|
159 <dt>VERSION</dt>
|
Chris@1
|
160 <dd>The version field may be used to differentiate multiple
|
Chris@1
|
161 versions of the same track title in a single collection.
|
Chris@1
|
162 (e.g. remix info)</dd>
|
Chris@1
|
163
|
Chris@1
|
164 <dt>ALBUM</dt>
|
Chris@1
|
165 <dd>The collection name to which this track belongs</dd>
|
Chris@1
|
166
|
Chris@1
|
167 <dt>TRACKNUMBER</dt>
|
Chris@1
|
168 <dd>The track number of this piece if part of a specific larger collection or album</dd>
|
Chris@1
|
169
|
Chris@1
|
170 <dt>ARTIST</dt>
|
Chris@1
|
171 <dd>The artist generally considered responsible for the work. In popular music
|
Chris@1
|
172 this is usually the performing band or singer. For classical music it would be
|
Chris@1
|
173 the composer. For an audio book it would be the author of the original text.</dd>
|
Chris@1
|
174
|
Chris@1
|
175 <dt>PERFORMER</dt>
|
Chris@1
|
176 <dd>The artist(s) who performed the work. In classical music this would be the
|
Chris@1
|
177 conductor, orchestra, soloists. In an audio book it would be the actor who did
|
Chris@1
|
178 the reading. In popular music this is typically the same as the ARTIST and
|
Chris@1
|
179 is omitted.</dd>
|
Chris@1
|
180
|
Chris@1
|
181 <dt>COPYRIGHT</dt>
|
Chris@1
|
182 <dd>Copyright attribution, e.g., '2001 Nobody's Band' or '1999 Jack Moffitt'</dd>
|
Chris@1
|
183
|
Chris@1
|
184 <dt>LICENSE</dt>
|
Chris@1
|
185 <dd>License information, eg, 'All Rights Reserved', 'Any
|
Chris@1
|
186 Use Permitted', a URL to a license such as a Creative Commons license
|
Chris@1
|
187 ("www.creativecommons.org/blahblah/license.html") or the EFF Open
|
Chris@1
|
188 Audio License ('distributed under the terms of the Open Audio
|
Chris@1
|
189 License. see http://www.eff.org/IP/Open_licenses/eff_oal.html for
|
Chris@1
|
190 details'), etc.</dd>
|
Chris@1
|
191
|
Chris@1
|
192 <dt>ORGANIZATION</dt>
|
Chris@1
|
193 <dd>Name of the organization producing the track (i.e.
|
Chris@1
|
194 the 'record label')</dd>
|
Chris@1
|
195
|
Chris@1
|
196 <dt>DESCRIPTION</dt>
|
Chris@1
|
197 <dd>A short text description of the contents</dd>
|
Chris@1
|
198
|
Chris@1
|
199 <dt>GENRE</dt>
|
Chris@1
|
200 <dd>A short text indication of music genre</dd>
|
Chris@1
|
201
|
Chris@1
|
202 <dt>DATE</dt>
|
Chris@1
|
203 <dd>Date the track was recorded</dd>
|
Chris@1
|
204
|
Chris@1
|
205 <dt>LOCATION</dt>
|
Chris@1
|
206 <dd>Location where track was recorded</dd>
|
Chris@1
|
207
|
Chris@1
|
208 <dt>CONTACT</dt>
|
Chris@1
|
209 <dd>Contact information for the creators or distributors of the track.
|
Chris@1
|
210 This could be a URL, an email address, the physical address of
|
Chris@1
|
211 the producing label.</dd>
|
Chris@1
|
212
|
Chris@1
|
213 <dt>ISRC</dt>
|
Chris@1
|
214 <dd>ISRC number for the track; see <a href="http://www.ifpi.org/isrc/">the
|
Chris@1
|
215 ISRC intro page</a> for more information on ISRC numbers.</dd>
|
Chris@1
|
216
|
Chris@1
|
217 </dl>
|
Chris@1
|
218
|
Chris@1
|
219 <h3>Implications</h3>
|
Chris@1
|
220
|
Chris@1
|
221 <ul>
|
Chris@1
|
222 <li>Field names should not be 'internationalized'; this is a
|
Chris@1
|
223 concession to simplicity not an attempt to exclude the majority of
|
Chris@1
|
224 the world that doesn't speak English. Field <emph>contents</emph>,
|
Chris@1
|
225 however, use the UTF-8 character encoding to allow easy representation
|
Chris@1
|
226 of any language.</li>
|
Chris@1
|
227 <li>We have the length of the entirety of the field and restrictions on
|
Chris@1
|
228 the field name so that the field name is bounded in a known way. Thus
|
Chris@1
|
229 we also have the length of the field contents.</li>
|
Chris@1
|
230 <li>Individual 'vendors' may use non-standard field names within
|
Chris@1
|
231 reason. The proper use of comment fields should be clear through
|
Chris@1
|
232 context at this point. Abuse will be discouraged.</li>
|
Chris@1
|
233 <li>There is no vendor-specific prefix to 'nonstandard' field names.
|
Chris@1
|
234 Vendors should make some effort to avoid arbitrarily polluting the
|
Chris@1
|
235 common namespace. We will generally collect the more useful tags
|
Chris@1
|
236 here to help with standardization.</li>
|
Chris@1
|
237 <li>Field names are not required to be unique (occur once) within a
|
Chris@1
|
238 comment header. As an example, assume a track was recorded by three
|
Chris@1
|
239 well know artists; the following is permissible, and encouraged:
|
Chris@1
|
240 <pre>
|
Chris@1
|
241 ARTIST=Dizzy Gillespie
|
Chris@1
|
242 ARTIST=Sonny Rollins
|
Chris@1
|
243 ARTIST=Sonny Stitt
|
Chris@1
|
244 </pre></li>
|
Chris@1
|
245 </ul>
|
Chris@1
|
246
|
Chris@1
|
247 <h2>Encoding</h2>
|
Chris@1
|
248
|
Chris@1
|
249 <p>The comment header comprises the entirety of the second bitstream
|
Chris@1
|
250 header packet. Unlike the first bitstream header packet, it is not
|
Chris@1
|
251 generally the only packet on the second page and may not be restricted
|
Chris@1
|
252 to within the second bitstream page. The length of the comment header
|
Chris@1
|
253 packet is (practically) unbounded. The comment header packet is not
|
Chris@1
|
254 optional; it must be present in the bitstream even if it is
|
Chris@1
|
255 effectively empty.</p>
|
Chris@1
|
256
|
Chris@1
|
257 <p>The comment header is encoded as follows (as per Ogg's standard
|
Chris@1
|
258 bitstream mapping which renders least-significant-bit of the word to be
|
Chris@1
|
259 coded into the least significant available bit of the current
|
Chris@1
|
260 bitstream octet first):</p>
|
Chris@1
|
261
|
Chris@1
|
262 <ol>
|
Chris@1
|
263 <li>Vendor string length (32 bit unsigned quantity specifying number of octets)</li>
|
Chris@1
|
264 <li>Vendor string ([vendor string length] octets coded from beginning of string
|
Chris@1
|
265 to end of string, not null terminated)</li>
|
Chris@1
|
266 <li>Number of comment fields (32 bit unsigned quantity specifying number of fields)</li>
|
Chris@1
|
267 <li>Comment field 0 length (if [Number of comment fields]>0; 32 bit unsigned
|
Chris@1
|
268 quantity specifying number of octets)</li>
|
Chris@1
|
269 <li>Comment field 0 ([Comment field 0 length] octets coded from beginning of
|
Chris@1
|
270 string to end of string, not null terminated)</li>
|
Chris@1
|
271 <li>Comment field 1 length (if [Number of comment fields]>1...)...</li>
|
Chris@1
|
272 </ol>
|
Chris@1
|
273
|
Chris@1
|
274 <p>This is actually somewhat easier to describe in code; implementation of the above
|
Chris@1
|
275 can be found in vorbis/lib/info.c:_vorbis_pack_comment(),_vorbis_unpack_comment()</p>
|
Chris@1
|
276
|
Chris@1
|
277 <div id="copyright">
|
Chris@1
|
278 The Xiph Fish Logo is a
|
Chris@1
|
279 trademark (™) of Xiph.Org.<br/>
|
Chris@1
|
280
|
Chris@1
|
281 These pages © 1994 - 2005 Xiph.Org. All rights reserved.
|
Chris@1
|
282 </div>
|
Chris@1
|
283
|
Chris@1
|
284 </body>
|
Chris@1
|
285 </html>
|