Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rzajac/riff
Package riff provides low level tools for working with files in Resource // Interchange File Format (RIFF).
https://github.com/rzajac/riff
Last synced: 3 days ago
JSON representation
Package riff provides low level tools for working with files in Resource // Interchange File Format (RIFF).
- Host: GitHub
- URL: https://github.com/rzajac/riff
- Owner: rzajac
- License: bsd-2-clause
- Created: 2020-12-18T12:17:31.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2023-03-24T20:44:53.000Z (over 1 year ago)
- Last Synced: 2024-06-20T11:58:50.035Z (5 months ago)
- Language: Go
- Size: 6.2 MB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
## RIFF file decoder and encoder
[![Go Report Card](https://goreportcard.com/badge/github.com/rzajac/riff)](https://goreportcard.com/report/github.com/rzajac/riff)
[![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg)](https://pkg.go.dev/github.com/rzajac/riff)Package provides low level tools for working with files in Resource Interchange
File Format (RIFF).Supported chunks:
* RIFF
* data
* fmt
* LIST
* INFO
* adtl
* labl
* ltxt
* samplPackage provides a way to register custom decoders for chunks not yet supported.
## Installation
```
go get github.com/rzajac/riff
```## Examples
See more examples in [_examples](_examples) directory.
### Print fmt chunk info
```
// Open file.
src, err := os.Open("path")
checkErr(err)
defer src.Close()// Create RIFF instance, read only metadata.
rif := riff.New(riff.SkipData)// Decode chunks.
_, err := rif.ReadFrom(src)
checkErr(err)// Get all sub-chunks.
chs := rif.Chunks()// Check the file has chunk we are interested in.
if chs.Count(riff.IDfmt) == 0 {
fmt.Printf(
"chunk %s not present in the file %s\n",
riff.Uint32(riff.IDfmt),
src.Name(),
)
return
}// Get the first fmt chunk.
// There should be only one of those in RIFF file,
// decoding would error out if there were more then one.
chi := chs.First(riff.IDfmt)// Cast to concrete type.
ch := chi.(*riff.ChunkFMT)fmt.Printf("Chunk fmt\n")
fmt.Printf(" - Compression Code: %#04x\n", ch.CompCode)
fmt.Printf(" - Channel Count: %d\n", ch.ChannelCnt)
fmt.Printf(" - Sample Rate: %d\n", ch.SampleRate)
fmt.Printf(" - Average Bit Rate: %d\n", ch.AvgByteRate)
fmt.Printf(" - Block Align: %d\n", ch.BlockAlign)
fmt.Printf(" - Bits Per Sample: %d\n", ch.BitsPerSample)extra, err := ioutil.ReadAll(ch.Extra())
checkErr(err)fmt.Printf(" - Extra fmt Bytes: %v\n", extra)
fmt.Println()
```### Reuse instance when decoding multiple files.
```
// Create RIFF instance, read only metadata.
rif := riff.New(riff.SkipData)for _, pth := range []string{"pth1", "pth2", "pth3"} {
src, err := os.Open("path")
checkErr(err)
defer src.Close()
_, err := rif.ReadFrom(src)
checkErr(err)
// Work on RIFF instance.
}
```### Register custom chunk decoders.
```
// Create registry and tell it what to use to handle unknown chunks.
reg := riff.NewRegistry(riff.RAWCMake(riff.SkipData))// Register one or more custom decoders.
reg.Register(IDfmt, FMTMake)// Create RIFF decoder.
rif := riff.Bare(reg)
```In the example above only "fmt " chunks will be decoded. The rest will be
skipped by `ChunkRAWC` decoder.### Save edits
```
// Open file.
src, err := os.Open("path")
checkErr(err)
defer src.Close()// Create RIFF instance.
rif := riff.New(riff.LoadData)// Decode chunks.
_, err = rif.ReadFrom(src)
checkErr(err)// Get all sub-chunks.
chs := rif.Chunks()// Check the file has chunk we are interested in.
if chs.Count(riff.IDfmt) == 0 {
fmt.Printf(
"chunk %s not present in the file %s\n",
riff.Uint32(riff.IDfmt),
src.Name(),
)
return
}// Get the first fmt chunk.
// There should be only one of those in RIFF file,
// decoding would error out if there were more then one.
chi := chs.First(riff.IDfmt)// Cast to concrete type.
ch := chi.(*riff.ChunkFMT)// Edit values.
ch.SampleRate = 44100dst, err := os.Create("new_file")
checkErr(err)_, err = rif.WriteTo(dst)
checkErr(err)
```## FAQ
### Can I reuse RIFF instance for multiple files?
Yes.
### Is the library thread safe?
No. It's up to the user to handle concurrency.
### How do I create custom decoder for chunk X?
Implement interface [Chunk](chunk.go) and register it. See example above.
### How unsupported chunks are handled?
Not supported chunks are decoded and encoded by `ChunkRAWC` so it's still
possible to decode -> edit -> encode a file with not supported chunks.## License
BSD-2-Clause