void MetadataCallback(IntPtr decoder, FLAC__StreamMetadata *metadata, void *client_data) { if (metadata->type == FLAC__MetadataType.FLAC__METADATA_TYPE_STREAMINFO) { m_pcm = new AudioPCMConfig( metadata->stream_info.bits_per_sample, metadata->stream_info.channels, metadata->stream_info.sample_rate, (AudioPCMConfig.SpeakerConfig) 0); m_sampleCount = metadata->stream_info.total_samples; } #if SUPPORTMETADATA if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { for (int tagno = 0; tagno < metadata->vorbis_comment.num_comments; tagno++) { char *field_name, *field_value; if (!FLACDLL.FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(metadata->vorbis_comment.comments[tagno], &field_name, &field_value)) { throw new Exception("Unable to parse vorbis comment."); } string name = Marshal::PtrToStringAnsi((IntPtr)field_name); free(field_name); array <Byte> ^ bvalue = new array <Byte>((int)strlen(field_value)); Marshal.Copy((IntPtr)field_value, bvalue, 0, (int)strlen(field_value)); free(field_value); UTF8Encoding enc = new UTF8Encoding(); string value = enc.GetString(bvalue); _tags.Add(name, value); } } #endif }
internal static extern int FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *metadata, int compact);
internal static extern int FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *metadata, int samples, long total_samples);
bool UpdateTags(bool preserveTime) { Close(); FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new(); if (!chain) { return(false); } IntPtr pathChars = Marshal::StringToHGlobalAnsi(_path); int res = FLAC__metadata_chain_read(chain, (const char *)pathChars.ToPointer()); Marshal::FreeHGlobal(pathChars); if (!res) { FLAC__metadata_chain_delete(chain); return(false); } FLAC__Metadata_Iterator *i = FLAC__metadata_iterator_new(); FLAC__metadata_iterator_init(i, chain); do { FLAC__StreamMetadata *metadata = FLAC__metadata_iterator_get_block(i); if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { FLAC__metadata_iterator_delete_block(i, false); } } while (FLAC__metadata_iterator_next(i)); FLAC__StreamMetadata *vorbiscomment = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT); for (int tagno = 0; tagno < _tags->Count; tagno++) { String ^ tag_name = _tags->GetKey(tagno); int tag_len = tag_name->Length; char * tag = new char [tag_len + 1]; IntPtr nameChars = Marshal::StringToHGlobalAnsi(tag_name); memcpy(tag, (const char *)nameChars.ToPointer(), tag_len); Marshal::FreeHGlobal(nameChars); tag[tag_len] = 0; array <string> ^ tag_values = _tags->GetValues(tagno); for (int valno = 0; valno < tag_values->Length; valno++) { UTF8Encoding ^ enc = new UTF8Encoding(); array <Byte> ^ value_array = enc->GetBytes(tag_values[valno]); int value_len = value_array->Length; char *value = new char [value_len + 1]; Marshal::Copy(value_array, 0, (IntPtr)value, value_len); value[value_len] = 0; FLAC__StreamMetadata_VorbisComment_Entry entry; /* create and entry and append it */ if (!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, tag, value)) { throw new Exception("Unable to add tags, must be valid utf8."); } if (!FLAC__metadata_object_vorbiscomment_append_comment(vorbiscomment, entry, /*copy=*/ false)) { throw new Exception("Unable to add tags."); } delete [] value; } delete [] tag; } FLAC__metadata_iterator_insert_block_after(i, vorbiscomment); FLAC__metadata_iterator_delete(i); FLAC__metadata_chain_sort_padding(chain); res = FLAC__metadata_chain_write(chain, true, preserveTime); FLAC__metadata_chain_delete(chain); return(0 != res); }