C Program for ID3 Tagging

Introduction:

Digital audio files can contain, in addition to the audio track, related text and/or graphical information. The information you’re probably familiar with take the form of Song title, Artist name, Album name, Year and Genre. This is the information displayed when you playback a digital audio file on your computer or portable device.

The process of including information other than sound into these digital audio files is commonly referred to as “tagging” in which you “tag” the audio file with additional information that describes the audio file. The original standard for tagging digital files was developed in 1996 by Eric Kemp and he coined the term ID3. At that time ID3 simply meant “IDentify an MP3”.



Versions of ID3:

There are majorly 2 versions of ID3, ID3v1 and ID3v2 as described below:

1. ID3v1: The MP3 standard did not include a method for storing file metadata. In 1996 Eric Kemp had the idea to add a small chunk of data to the audio file, thus solving the problem. The method, now known as ID3v1, quickly became the standard for storing metadata in MP3s.

The ID3v1 tag occupies 128 bytes, beginning with the string TAG 128 bytes from the end of the file. The tag was placed at the end of the file to maintain compatibility with older media players. Some players would play a small burst of static when they read the tag, but most ignored it, and almost all modern players will correctly skip it. This tag allows 30 bytes each for the title, artist, album, and a “comment”, four bytes for the year, and a byte to identify the genre of the song from a predefined list of 80 values (Winamp later extended this list to 148 values).

One improvement to ID3v1 was made by Michael Mutschler in 1997. Since the comment field was too small to write anything useful, he decided to trim it by two bytes and use those two bytes to store the track number. Such tags are referred to as ID3v1.1

2. ID3v2: In 1998, a new specification called ID3v2 was created by multiple contributors.[13] Although it bears the name ID3, its structure is very different from ID3v1.

ID3v2 tags are of variable size, and usually occur at the start of the file, which aids streaming media as the metadata is essentially available as soon as the file starts streaming instead of requiring the entire file to be read first as is the case with ID3v1. ID3v2 tags consist of a number of frames, each of which contains a piece of metadata. For example, the TIT2 frame contains the title, and the WOAR frame contains the URL of the artist’s website. Frames can be up to 16MB in length, while total tag size is limited to 256MB. The internationalization problem was solved by allowing the encoding of strings not only in ISO-8859-1, but also in Unicode. ID3v2 has further sub classifications to 3 versions as ID3v2.2, ID3v2.3 and ID3v2.4 with minor changes in frames amongst them.

ID3 Taggers:

ID3 tags may be edited in a variety of ways. On some platforms the file’s properties may be edited by viewing extended information in the file manager. Additionally most audio players allow editing single or groups of files. Editing groups of files is often referred to as “batch tagging”. There are also specialized applications, called taggers, which concentrate specifically on editing the tags and related tasks. Some, such as puddletag offer advanced features such as advanced batch tagging or editing based on regular expressions.

Below is the code for implementing your own tagger.

Examples:

Input: Input MP3 file name which needs to tagged like input.mp3 and output MP3 
file name which would be created as a tagged MP3 file like output.mp3.

Output: MP3 file with tagging information as entered by the user.

Below is the C code for implementing your own tagger:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C program for ID3 tagging of music files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
  
struct tags // Structure to store tagging information.
{
    char title[100], artist[100], album[100], 
         track_num[100], year[100], genre[100];
};
  
void merge_file(char* file1, char* file2, char* file3)
{
    FILE *f1, *f2, *f3;
    int ch;
    f1 = fopen(file1, "rb"); // Opening in write mode.
    f2 = fopen(file2, "rb");
    f3 = fopen(file3, "wb");
  
    if (f1 == NULL || f2 == NULL) {
        exit(EXIT_FAILURE);
    }
  
    while ((ch = fgetc(f1)) != EOF) // Appending tagging info.
        fputc(ch, f3);
  
    while ((ch = fgetc(f2)) != EOF) // Appending media file info.
        fputc(ch, f3);
  
    // Closing the files.
    fclose(f1);
    fclose(f2);
    fclose(f3);
}
  
void tagging(char* file1, char* file2, char* file3)
{
    int size = 0;
    char clean[100];
    struct tags t;
    unsigned char pad1[7] = { 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76 };
    unsigned char pad2[3] = { 0x00, 0x00, 0x00 };
  
    FILE* f1;
    f1 = fopen(file1, "wb");
  
    fprintf(f1, "ID3");
    fwrite(pad1, sizeof(pad1), 1, f1); /*Essential tag to identify 
                                        as an ID3 tagged media file.*/
  
    gets(clean); // Clearing the input stream.
  
    // Taking input from user.
    printf("\nEnter the title of the mp3:");
    scanf("%[^\n]%*c", t.title);
  
    printf("\nEnter the artist of the mp3:");
    scanf("%[^\n]%*c", t.artist);
  
    printf("\nEnter the album of the mp3.\n");
    scanf("%[^\n]%*c", t.album);
  
    printf("\nEnter the year of the mp3.\n");
    scanf("%[^\n]%*c", t.year);
  
    printf("\nEnter the track number of the mp3.\n");
    scanf("%[^\n]%*c", t.track_num);
  
    // Track Number
    // Tag to identify track number.
    fprintf(f1, "TRCK"); 
  
    // Essential 3 NULL bits required for seperation.
    fwrite(pad2, sizeof(pad2), 1, f1); 
  
    size = strlen(t.track_num);
    size++; // Calculating size.
  
     // Appending the size of the track number to tag.
    fprintf(f1, "%c", size);
  
    // Essential 3 NULL bits required for seperation.
    fwrite(pad2, sizeof(pad2), 1, f1);
  
    // Adding tag number entered by the user.
    fprintf(f1, "%s", t.track_num); 
  
    // Print Year
    fprintf(f1, "TYER"); 
    fwrite(pad2, sizeof(pad2), 1, f1); 
    size = strlen(t.year);
    size++; // Calculating size.
    fprintf(f1, "%c", size);
    fwrite(pad2, sizeof(pad2), 1, f1); 
    fprintf(f1, "%s", t.year); 
  
    // Print Title
    fprintf(f1, "TIT2"); 
    fwrite(pad2, sizeof(pad2), 1, f1); 
    size = strlen(t.title);
    size++; // Calculating size.
    fprintf(f1, "%c", size);
    fwrite(pad2, sizeof(pad2), 1, f1); 
    fprintf(f1, "%s", t.title);
  
    // Print Artist
    fprintf(f1, "TPE1"); 
    fwrite(pad2, sizeof(pad2), 1, f1); 
    size = strlen(t.artist);
    size++; // Calculating size.
    fprintf(f1, "%c", size);
    fwrite(pad2, sizeof(pad2), 1, f1); 
    fprintf(f1, "%s", t.artist); 
  
    // Print Album
    fprintf(f1, "TALB"); 
    fwrite(pad2, sizeof(pad2), 1, f1); 
    size = strlen(t.album);
    size++; // Calculating size.
    fprintf(f1, "%c", size);
    fwrite(pad2, sizeof(pad2), 1, f1); 
    fprintf(f1, "%s", t.album); 
  
    // Print Genre
    fprintf(f1, "TCON"); // Tag to identify genre.
    fwrite(pad2, sizeof(pad2), 1, f1);
    size = strlen(t.genre);
    size++; // Calculating size.
    fprintf(f1, "%c", size); 
    fwrite(pad2, sizeof(pad2), 1, f1); 
    fprintf(f1, "%s", t.genre); 
  
    fclose(f1); // Closing the file.
}
  
int main()
{
    char file1[100] = "media_info.txt", file2[100], file3[100];
  
    printf("\nEnter the input mp3 file name\n");
    scanf("%s", file2);
    printf("\nEnter the output mp3 file name\n");
    scanf("%s", file3);
  
    // Function to append media info to input file.
    tagging(file1, file2, file3); 
  
    // Function to merge media info and media
    // input file.
    merge_file(file1, file2, file3); 
    return 0;
}

chevron_right


Note: The folder in which you are running the code should contain your input.mp3 file.

References:
http://id3.org/id3v2.3.0
https://en.wikipedia.org/wiki/ID3#ID3v2



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.