-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FLAC Encoder, metadata support #14
Comments
Support for encoding metadata has been added. Proper support for encoding audio samples is yet to be implemented. For now, simply copy the original encoded audio data from the source FLAC file. The API mirrors that of image.Encode. Updates #14.
Hi @varyoo!
I'm really glad to hear you've enjoyed playing with the library so far! My brother and I had a lot of fun developing it. The intention is to support both encoding and decoding, and to provide high-level access to these features through the Azul3D audio interface. As of commit 306014a, preliminary encoding support has been added, using an API which mirrors image.Encode. // Encode writes the FLAC audio stream to w.
func Encode(w io.Writer, stream *Stream) error Encoding of metadata blocks is now supported. Proper support for encoding audio samples is yet to be implemented. For now, the encoded samples of the original FLAC stream are copied verbatim to the output stream. For an example of how to update metadata blocks, please take a look at the following code hosted at play.golang.org, which decodes the P.S. Anyone who wishes to tackle implementing proper support for encoding audio samples is welcome to do so :) |
I'm amazed, thanks for support! Vorbis comments changes seems to be working. But I don't get how the length written in the block header can follow tags changes. From what I understand:
Are we going further? Did I get something wrong? What is your point of view on these points? |
@varyoo It involves linear search and so called slice tricks. // First you have to find the block you want to remove, for instance padding as you mentioned earlier.
index := -1
for i, block := range stream.Blocks {
if block.Type == meta.TypePadding {
index = i
break
}
}
// Then delete the specific index in the slice.
if index != -1 {
stream.Blocks = append(stream.Blocks[:index], stream.Blocks[index+1:]...)
} Link for play.golang.org |
Thanks for pointing this out. It's a bug and should be fixed. |
I would like to propose that we treat the FLAC stream, metadata block and frame data structures in a similar fashion as one would treat an AST. They will basically contain the semantically relevant information required to recreate the a FLAC file containing the same metadata and audio samples. These data structures may be arbitrarily manipulated by the user prior to encoding, and even created afresh from memory (possibly produced by hand, procedurally generated, or generated by tools such as Go-fuzz). Keeping with the idea that we may not foresee all possible use cases, and cannot create an API which would satisfy all future needs, we should instead focus on a separation of concern, and keep these data structures clean. To facilitate manipulation of metadata (and audio samples), a set of utility packages may be written, which could provide convenience functions for adding and removing metadata blocks (basically using For reference, the idea of separation the data structures from a set of utility packages which manipulate said data structures is also being evaluated by the |
Yes, but, for example
Isn't it procedural vs OOP? |
Good catch. Will have to think about how to solve this in a clean manner. |
This has been fixed as of commit c6cd3f7. |
The following example hosted at play.golang.org utilizes a metadata utility package to remove padding metadata blocks, add Vorbis comments and append a custom metadata block. Providing the relevant extract below. func updateMetadata(stream *flac.Stream) {
// Remove padding metadata blocks.
metautil.RemoveBlockType(stream, meta.TypePadding)
// Add metadata comments.
comment := metautil.NewCommentBlock("foobar")
comment.Add("testing", "hello world :)")
metautil.AppendBlockBody(stream, comment.Body)
// Add a custom metadata block.
block := &meta.Block{
Header: meta.Header{
Type: meta.TypeApplication,
},
Body: &meta.Application{
ID: 0xDEADBEEF,
Data: []byte("Arbitrary data.\n"),
},
}
metautil.AppendBlock(stream, block)
} Note that the @varyoo Feel free to suggest possible improvements, or fork the package to play on your own as you may have a concrete use-case in mind :) Input FLAC stream metadata
Output FLAC stream metadata
|
I get the idea now, it means that This is what I needed, I understand this package is part of a bigger project, thank you. |
Lovely to hear. When you are happy with the implementation, would you mind closing this issue? We can open a dedicated issue for the future ambition of implementing encoding support for audio samples. This issue will be dedicated to metadata blocks. |
I want to update some metadata blocks (Vorbis comments) and re-encode the
Stream
.Is it planned? If not, any hints on how to do it (within the current API design)?
I love how close this library is to the FLAC specifications, I enjoyed using it, thank you.
The text was updated successfully, but these errors were encountered: