static void add_tag(vorbis_comment *vc, oe_options *opt,char *name, char *value) { char *utf8; if (opt->isutf8) { if (!utf8_validate(value)) { fprintf(stderr, _("'%s' is not valid UTF-8, cannot add\n"), name?name:"comment"); } else { if(name == NULL) { vorbis_comment_add(vc, value); } else { vorbis_comment_add_tag(vc, name, value); } } } else if(utf8_encode(value, &utf8) >= 0) { if(name == NULL) { vorbis_comment_add(vc, utf8); } else { vorbis_comment_add_tag(vc, name, utf8); } free(utf8); } else { fprintf(stderr, _("Couldn't convert comment to UTF-8, cannot add\n")); } }
void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents){ char *comment=alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */ strcpy(comment, tag); strcat(comment, "="); strcat(comment, contents); vorbis_comment_add(vc, comment); }
int unpack_vorbis_comments(vorbis_comment *vc, const void *data, UInt32 data_size) { int i; char *dptr = (char *) data; char *dend = dptr + data_size; int len = EndianU32_LtoN(*(UInt32 *)dptr); int commnum = 0; char save; dptr += 4 + len; if (len >= 0 && dptr < dend) { commnum = EndianU32_LtoN(*(UInt32 *)dptr); if (commnum >= 0) { dptr += 4; for (i = 0; i < commnum && dptr <= dend; i++) { len = EndianU32_LtoN(*(UInt32 *)dptr); dptr += 4; if (dptr + len > dend) break; save = *(dptr + len); *(dptr + len) = '\0'; vorbis_comment_add(vc, dptr); dptr += len; *dptr = save; } } } return 0; }
void format_set_vorbiscomment(format_plugin_t *plugin, const char *tag, const char *value) { if (vorbis_comment_query_count(&plugin->vc, tag) != 0) { /* delete key */ /* as libvorbis hides away all the memory functions we need to copy * the structure comment by comment. sorry about that... */ vorbis_comment vc; int i; /* why does vorbis_comment use int, not size_t? */ size_t keylen = strlen(tag); vorbis_comment_init(&vc); /* copy tags */ for (i = 0; i < plugin->vc.comments; i++) { if (strncasecmp(plugin->vc.user_comments[i], tag, keylen) == 0 && plugin->vc.user_comments[i][keylen] == '=') continue; vorbis_comment_add(&vc, plugin->vc.user_comments[i]); } /* move vendor */ vc.vendor = plugin->vc.vendor; plugin->vc.vendor = NULL; vorbis_comment_clear(&plugin->vc); plugin->vc = vc; } vorbis_comment_add_tag(&plugin->vc, tag, value); }
void BURGERCALL vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents){ char *comment=static_cast<char *>(AllocAPointer(strlen(tag)+strlen(contents)+2)); /* +2 for = and \0 */ strcpy(comment, tag); strcat(comment, "="); strcat(comment, contents); vorbis_comment_add(vc, comment); DeallocAPointer(comment); }
/* * Save field value in a single tag */ static gboolean Ogg_Write_Tag (vorbis_comment *vc, const gchar *tag_name, gchar *value) { char *string = g_strconcat(tag_name,value,NULL); vorbis_comment_add(vc,string); g_free(string); return TRUE; }
void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents){ /* Length for key and value +2 for = and \0 */ char *comment=_ogg_malloc(strlen(tag)+strlen(contents)+2); strcpy(comment, tag); strcat(comment, "="); strcat(comment, contents); vorbis_comment_add(vc, comment); _ogg_free(comment); }
static void metadata_update(void *self, vorbis_comment *vc) { im_sndio_state *s = self; char **md; thread_mutex_lock(&s->metadatalock); md = s->metadata; if(md) { while(*md) vorbis_comment_add(vc, *md++); } thread_mutex_unlock(&s->metadatalock); }
/* This handles the headers at the backend, here we insert the header packets * we want for the queue. */ static int process_vorbis_headers (ogg_state_t *ogg_info, ogg_codec_t *codec) { vorbis_codec_t *source_vorbis = codec->specific; if (source_vorbis->header [0] == NULL) return 0; DEBUG0 ("Adding the 3 header packets"); ogg_stream_packetin (&source_vorbis->new_os, source_vorbis->header [0]); /* NOTE: we could build a separate comment packet each time */ if (source_vorbis->rebuild_comment) { vorbis_comment vc; ogg_packet header; vorbis_comment_init (&vc); if (ogg_info->artist) vorbis_comment_add_tag (&vc, "artist", ogg_info->artist); if (ogg_info->title) vorbis_comment_add_tag (&vc, "title", ogg_info->title); vorbis_comment_add (&vc, "server=" ICECAST_VERSION_STRING); vorbis_commentheader_out (&vc, &header); ogg_stream_packetin (&source_vorbis->new_os, &header); vorbis_comment_clear (&vc); ogg_packet_clear (&header); } else ogg_stream_packetin (&source_vorbis->new_os, source_vorbis->header [1]); ogg_stream_packetin (&source_vorbis->new_os, source_vorbis->header [2]); source_vorbis->rebuild_comment = 0; ogg_info->log_metadata = 1; source_vorbis->get_buffer_page = get_buffer_header; source_vorbis->process_packet = process_vorbis_audio; source_vorbis->granulepos = source_vorbis->prev_window; source_vorbis->initial_audio_packet = 1; return 1; }
int lame_encode_ogg_init(lame_global_flags *gfp) { lame_internal_flags *gfc=gfp->internal_flags; char comment[MAX_COMMENT_LENGTH+1]; /********** Encode setup ************/ /* choose an encoding mode */ /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */ if (gfp->compression_ratio < 5.01) { memcpy(&vi2,&info_E,sizeof(vi2)); MSGF( gfc, "Encoding with Vorbis mode info_E \n" ); } else if (gfp->compression_ratio < 6) { memcpy(&vi2,&info_D,sizeof(vi2)); MSGF( gfc, "Encoding with Vorbis mode info_D \n" ); } else if (gfp->compression_ratio < 8) { memcpy(&vi2,&info_C,sizeof(vi2)); MSGF( gfc, "Encoding with Vorbis mode info_C \n" ); } else if (gfp->compression_ratio < 10) { memcpy(&vi2,&info_B,sizeof(vi2)); MSGF( gfc, "Encoding with Vorbis mode info_B \n" ); } else if (gfp->compression_ratio < 12) { memcpy(&vi2,&info_A,sizeof(vi2)); MSGF( gfc, "Encoding with Vorbis mode info_A \n" ); } else { memcpy(&vi2,&info_A,sizeof(vi2)); MSGF( gfc, "Encoding with Vorbis mode info_A \n" ); } vi2.channels = gfc->channels_out; vi2.rate = gfp->out_samplerate; /* add a comment */ vorbis_comment_init(&vc2); vorbis_comment_add(&vc2,"Track encoded using L.A.M.E. libvorbis interface."); /* Add ID3-style comments to the output using (for the time being) the "private data members" in the "id3tag_spec" data structure. This was from a patch by Ralph Giles <*****@*****.**> */ #ifdef THIS_CODE_IS_NOT_BROKEN_ANYMORE if(gfp->tag_spec.title) { strcpy(comment,"TITLE="); strncat(comment,gfp->tag_spec.title,MAX_COMMENT_LENGTH-strlen(comment)); vorbis_comment_add(&vc2,comment); } if(gfp->tag_spec.artist) { strcpy(comment,"ARTIST="); strncat(comment,gfp->tag_spec.artist,MAX_COMMENT_LENGTH-strlen(comment)); vorbis_comment_add(&vc2,comment); } if(gfp->tag_spec.album) { strcpy(comment,"ALBUM="); strncat(comment,gfp->tag_spec.album,MAX_COMMENT_LENGTH-strlen(comment)); vorbis_comment_add(&vc2,comment); } /* pretend that the ID3 fields are equivalent to the Vorbis fields */ if(gfp->tag_spec.year) { sprintf(comment, "DATE=%d", gfp->tag_spec.year); vorbis_comment_add(&vc2,comment); } if(gfp->tag_spec.comment) { strcpy(comment,"DESCRIPTION="); strncat(comment,gfp->tag_spec.comment,MAX_COMMENT_LENGTH-strlen(comment)); vorbis_comment_add(&vc2,comment); } /* TODO -- support for track and genre */ #endif /* set up the analysis state and auxiliary encoding storage */ vorbis_analysis_init(&vd2,&vi2); vorbis_block_init(&vd2,&vb2); /* set up our packet->stream encoder */ /* pick a random serial number; that way we can more likely build chained streams just by concatenation */ srand(time(NULL)); ogg_stream_init(&os2,rand()); /* Vorbis streams begin with three headers; the initial header (with most of the codec setup parameters) which is mandated by the Ogg bitstream spec. The second header holds any comment fields. The third header holds the bitstream codebook. We merely need to make the headers, then pass them to libvorbis one at a time; libvorbis handles the additional Ogg bitstream constraints */ { ogg_packet header; ogg_packet header_comm; ogg_packet header_code; vorbis_analysis_headerout(&vd2,&vc2,&header,&header_comm,&header_code); ogg_stream_packetin(&os2,&header); /* automatically placed in its own page */ ogg_stream_packetin(&os2,&header_comm); ogg_stream_packetin(&os2,&header_code); /* no need to write out here. We'll get to that in the main loop */ } return 0; }
static void add_list(vorbis_comment *vc, char **comments) { while (*comments) vorbis_comment_add(vc, *comments++); }
gboolean Ogg_Tag_Write_File_Tag (ET_File *ETFile) { File_Tag *FileTag; gchar *filename; gchar *filename_utf8; gchar *basename_utf8; FILE *file_in; vcedit_state *state; vorbis_comment *vc; gchar *string; GList *list; Picture *pic; if (!ETFile || !ETFile->FileTag) return FALSE; FileTag = (File_Tag *)ETFile->FileTag->data; filename = ((File_Name *)ETFile->FileNameCur->data)->value; filename_utf8 = ((File_Name *)ETFile->FileNameCur->data)->value_utf8; ogg_error_msg = NULL; /* Test to know if we can write into the file */ if ( (file_in=fopen(filename,"rb"))==NULL ) { Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno)); return FALSE; } { // Skip the id3v2 tag guchar tmp_id3[4]; gulong id3v2size; // Check if there is an ID3v2 tag... fseek(file_in, 0L, SEEK_SET); if (fread(tmp_id3, 1, 4, file_in) == 4) { // Calculate ID3v2 length if (tmp_id3[0] == 'I' && tmp_id3[1] == 'D' && tmp_id3[2] == '3' && tmp_id3[3] < 0xFF) { // id3v2 tag skipeer $49 44 33 yy yy xx zz zz zz zz [zz size] fseek(file_in, 2, SEEK_CUR); // Size is 6-9 position if (fread(tmp_id3, 1, 4, file_in) == 4) { id3v2size = 10 + ( (long)(tmp_id3[3]) | ((long)(tmp_id3[2]) << 7) | ((long)(tmp_id3[1]) << 14) | ((long)(tmp_id3[0]) << 21) ); fseek(file_in, id3v2size, SEEK_SET); }else { fseek(file_in, 0L, SEEK_SET); } }else { fseek(file_in, 0L, SEEK_SET); } }else { fseek(file_in, 0L, SEEK_SET); } } state = vcedit_new_state(); // Allocate memory for 'state' if ( vcedit_open(state,file_in) < 0 ) { Log_Print(LOG_ERROR,_("ERROR: Failed to open file: '%s' as vorbis (%s)."),filename_utf8,vcedit_error(state)); ogg_error_msg = vcedit_error(state); fclose(file_in); vcedit_clear(state); return FALSE; } /* Get data from tag */ vc = vcedit_comments(state); vorbis_comment_clear(vc); vorbis_comment_init(vc); /********* * Title * *********/ Ogg_Set_Tag(vc,"TITLE=",FileTag->title,VORBIS_SPLIT_FIELD_TITLE); /********** * Artist * **********/ Ogg_Set_Tag(vc,"ARTIST=",FileTag->artist, VORBIS_SPLIT_FIELD_ARTIST); /**************** * Album Artist * ****************/ Ogg_Set_Tag(vc,"ALBUMARTIST=",FileTag->album_artist, VORBIS_SPLIT_FIELD_ARTIST); /********* * Album * *********/ Ogg_Set_Tag(vc,"ALBUM=",FileTag->album, VORBIS_SPLIT_FIELD_ALBUM); /*************** * Disc Number * ***************/ Ogg_Set_Tag(vc,"DISCNUMBER=",FileTag->disc_number,FALSE); /******** * Year * ********/ Ogg_Set_Tag(vc,"DATE=",FileTag->year,FALSE); /************************* * Track and Total Track * *************************/ Ogg_Set_Tag(vc,"TRACKNUMBER=",FileTag->track,FALSE); Ogg_Set_Tag(vc,"TRACKTOTAL=",FileTag->track_total,FALSE); /********* * Genre * *********/ Ogg_Set_Tag(vc,"GENRE=",FileTag->genre,VORBIS_SPLIT_FIELD_GENRE); /*********** * Comment * ***********/ // We write the comment using the two formats "DESCRIPTION" and "COMMENT" to be compatible with old versions // Format of new specification Ogg_Set_Tag(vc,"DESCRIPTION=",FileTag->comment,VORBIS_SPLIT_FIELD_COMMENT); // Format used in winamp plugin Ogg_Set_Tag(vc,"COMMENT=",FileTag->comment,VORBIS_SPLIT_FIELD_COMMENT); if (OGG_TAG_WRITE_XMMS_COMMENT) { // Format used into xmms-1.2.5 Ogg_Set_Tag(vc,"=",FileTag->comment,VORBIS_SPLIT_FIELD_COMMENT); } /************ * Composer * ************/ Ogg_Set_Tag(vc,"COMPOSER=",FileTag->composer,VORBIS_SPLIT_FIELD_COMPOSER); /******************* * Original artist * *******************/ Ogg_Set_Tag(vc,"PERFORMER=",FileTag->orig_artist,VORBIS_SPLIT_FIELD_ORIG_ARTIST); /************* * Copyright * *************/ Ogg_Set_Tag(vc,"COPYRIGHT=",FileTag->copyright,FALSE); /******* * URL * *******/ Ogg_Set_Tag(vc,"LICENSE=",FileTag->url,FALSE); /************** * Encoded by * **************/ Ogg_Set_Tag(vc,"ENCODED-BY=",FileTag->encoded_by,FALSE); /*********** * Picture * ***********/ pic = FileTag->picture; while (pic) { if (pic->data) { gchar *data_encoded = NULL; gint size; Picture_Format format = Picture_Format_From_Data(pic); string = g_strdup_printf("COVERARTMIME=%s",Picture_Mime_Type_String(format)); vorbis_comment_add(vc,string); g_free(string); if (pic->type) { string = g_strdup_printf("COVERARTTYPE=%d",pic->type); vorbis_comment_add(vc,string); g_free(string); } if (pic->description) { string = g_strdup_printf("COVERARTDESCRIPTION=%s",pic->description); vorbis_comment_add(vc,string); g_free(string); } size = base64_encode(pic->data, pic->size, &data_encoded); string = g_strdup_printf("COVERART=%s",data_encoded); vorbis_comment_add(vc,string); g_free(data_encoded); g_free(string); } pic = pic->next; } /************************** * Set unsupported fields * **************************/ list = FileTag->other; while (list) { if (list->data) vorbis_comment_add(vc,(gchar *)list->data); list = list->next; } /* Write tag, and close also 'file_in' in all cases */ if ( Ogg_Tag_Write_File(file_in,filename,state) == FALSE ) { ogg_error_msg = vcedit_error(state); Log_Print(LOG_ERROR,_("ERROR: Failed to write comments to file '%s' (%s)."),filename_utf8,ogg_error_msg == NULL ? "" : ogg_error_msg); vcedit_clear(state); return FALSE; }else { basename_utf8 = g_path_get_basename(filename_utf8); Log_Print(LOG_OK,_("Written tag of '%s'"),basename_utf8); vcedit_clear(state); } return TRUE; }
static int ogg_output_open(const char *fname, const char *comment) { int fd; static vorbis_info ogg_info; vorbis_info *vi; /* struct that stores all the static vorbis bitstream settings */ vorbis_comment vc; /* struct that stores all the user comments */ if(strcmp(fname, "-") == 0) { fd = 1; /* data to stdout */ if(comment == NULL) comment = "(stdout)"; } else { /* Open the audio file */ fd = open(fname, FILE_OUTPUT_MODE); if(fd < 0) { ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s", fname, strerror(errno)); return -1; } if(comment == NULL) comment = fname; } /* choose an encoding mode */ /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */ memcpy(&ogg_info, &info_A, sizeof(ogg_info)); if(dpm.encoding & PE_MONO) ogg_info.channels = 1; else ogg_info.channels = 2; ogg_info.rate = dpm.rate; vi = &ogg_info; /* add a comment */ vorbis_comment_init(&vc); vorbis_comment_add(&vc, (char *)comment); /* set up the analysis state and auxiliary encoding storage */ vorbis_analysis_init(&vd, vi); vorbis_block_init(&vd, &vb); /* set up our packet->stream encoder */ /* pick a random serial number; that way we can more likely build chained streams just by concatenation */ srand(time(NULL)); ogg_stream_init(&os, rand()); /* Vorbis streams begin with three headers; the initial header (with most of the codec setup parameters) which is mandated by the Ogg bitstream spec. The second header holds any comment fields. The third header holds the bitstream codebook. We merely need to make the headers, then pass them to libvorbis one at a time; libvorbis handles the additional Ogg bitstream constraints */ { ogg_packet header; ogg_packet header_comm; ogg_packet header_code; vorbis_analysis_headerout(&vd, &vc, &header, &header_comm, &header_code); ogg_stream_packetin(&os, &header); /* automatically placed in its own page */ ogg_stream_packetin(&os, &header_comm); ogg_stream_packetin(&os, &header_code); /* no need to write out here. We'll get to that in the main loop */ } return fd; }