title: How to retrieve ID3 tag information from PCM (WAV) file using the LAME encoder library?
body: <p>I have a problem retrieving tag information from a test WAV file (no sound, just empty WAV file).</p>
  <p>Here is how I initialize LAME:</p>
  <pre><code>lame_global_flags*  lame = NULL;
  lame = lame_init();
  lame_set_in_samplerate(lame, 44100);
  lame_set_VBR(lame, vbr_default);
  id3tag_init(lame);
  id3tag_add_v2(lame);
  id3tag_v2_only(lame);
  lame_set_write_id3tag_automatic(lame, 1);
  // id3tag_set_artist(lame, &quot;Test artist&quot;);
   // id3tag_set_album(lame, &quot;Test ablum&quot;);
  lame_init_params(lame);
  </code></pre>
  <p>And here is how I try to retrieve the tag:</p>
  <pre><code>unsigned char buffer[256];
  size_t id3tagSize = lame_get_id3v2_tag(lame, buffer, sizeof(buffer));
  </code></pre>
  <p>which to be honest doesn't really help the situation since it doesn't involve the file that has been read (see code below).</p>
  <p>Here is a HEX view of my input PCM file (just the ID3 tag info data chunk):</p>
  <p><a href="https://i.stack.imgur.com/w8FPd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/w8FPd.png" alt="enter image description here" /></a></p>
  <p>You can see information chunks containing <strong>TIT2</strong> (title), <strong>TALB</strong> (album), <strong>TPUB</strong> (publisher) etc. (see list of all ID3 tag names <a href="https://exiftool.org/TagNames/ID3.html" rel="nofollow noreferrer">here</a>), which means that the information is there but the LAME encoder seems to ignore it.</p>
  <p>If a tag name is not empty it is followed by a specific number of bytes based on my observations. For example <strong>TIT2</strong> is followed by <code>0x00 0x00 0x00 0x08</code>, which converted to decimal represents the <code>length+1</code> of the title, which is <code>&quot;Message&quot;</code> plus padding with <code>0x00</code>.</p>
  <p>However if I enter a total number of tracks <code>TRACKTOTAL</code> I get 1 <code>0x00</code> byte (probably padding) plus an arbitrary number of bytes, each containing the hexademical code representation of digits. For example if I put <code>300</code> as the number of total tracks I will get <code>54 52 41 43 4b 54 4f 54 41 4c 00 33 30 30</code>, which in terms can be converted to a string <code>TRACKTOTAL 300</code>.</p>
  <p>I can try to manually parse this information but I'd rather spend my time on working on another part of my code. There are non-standard tag names, tag information is usually placed either at the beginning or at the end of a file (based on the specification for RIFF WAVE files) etc. Don't want to write my own ID3 tag parsers. -_-</p>
  <p>At first I didn't try to configure anything related to tagging. According to the <code>lame.h</code> the default (unless tagging is disabled) behaviour for LAME is to enable <code>lame_set_write_id3tag_automatic(lame_global_flags * gfp, int)</code> (the <code>int</code> parameter). My initial code was:</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;lame.h&gt;
  
  int main(int argc, char* argv[])
  {
      int read = 0;
      int write = 0;
  
      char* path = argv[1];
      printf(&quot;WAV input: %s\n&quot;, path);
      FILE *pcm = fopen(path, &quot;rb&quot;);
      FILE *mp3 = fopen(&quot;output.mp3&quot;, &quot;wb&quot;);
  
      fseek(pcm, 0, SEEK_END);
      const int PCM_SIZE = ftell(pcm);
      fseek(pcm, 0, SEEK_SET);
      const int MP3_SIZE = PCM_SIZE;
  
      short int pcm_buffer[PCM_SIZE * 2];
      unsigned char mp3_buffer[MP3_SIZE];
  
  
      lame_global_flags*  lame = NULL;
      lame = lame_init();
      lame_set_in_samplerate(lame, 44100);
      lame_set_VBR(lame, vbr_default);
      lame_init_params(lame);
  
      do
      {
          read = fread(pcm_buffer, 2 * sizeof(short int), PCM_SIZE, pcm);
          if (read == 0)
          {
              // TODO Retrieve ID3 tag here? Copy?
              write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
          }
          else
          {
              write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
          }
          fwrite(mp3_buffer, write, 1, mp3);
      }
      while (read != 0);
  
      lame_close(lame);
      fclose(mp3);
      fclose(pcm);
  </code></pre>
  <p>However even though a MP3 file was produced and all the audio data was in it (I also tried with other WAV files of course) the ID3 tag information was gone.</p>
  <p>Setting the ID3 tag manually by using <code>id3tag_set_artist(...)</code>, <code>id3tag_set_album(...)</code> etc.) works. However I am looking for a way to <strong>copy the ID3 tag from the source (PCM) into the destination (MP3)</strong>. The documentation of LAME is basically its header, which is not really that great. I was unable to find anything related to copying the tag except for the <code>lame_set_write_id3tag_automatic(...)</code>.</p>
  <p>I tried both ID3v1 and ID3v2 since ID3v2 is generated only if one of the text fields doesn't fit into a ID3v1 but on the other hand forcing ID3v2 should override this setting.</p>
  <p>In addition <code>lame_encode_flush(...)</code> is supposed  to write any ID3v1 tags.</p>