Skip to content
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

Feature request: writing wav to stdout and other !Seek sinks. #33

Open
vi opened this issue Mar 14, 2019 · 5 comments
Open

Feature request: writing wav to stdout and other !Seek sinks. #33

vi opened this issue Mar 14, 2019 · 5 comments

Comments

@vi
Copy link
Contributor

vi commented Mar 14, 2019

Just set duration in header to maximum possible.

@ruuda
Copy link
Owner

ruuda commented Mar 16, 2019

What do you want to achieve exactly? Do the samples ever end, and should the output be a valid wav file at that point? Is there a specific reason for choosing a maximal duration, or does your use case ignore the duration anyway?

One thing that might be possible is to only require W: io::Write on WavWriter, but to add the constraint W: io::Seek to WavWriter::flush() and WavWriter::finalize(). That would make it impossible to properly finalize the file on drop, but it is better to explicitly call finalize() anyway.

@vi
Copy link
Contributor Author

vi commented Mar 16, 2019

Just do like other multimedia command-line tools do: use 0xFFFFFFFF as chunk and data subchunk size initially, then patch it up to correct size on finalize if seeking is available (and just leave unpatched header otherwise).

Hound also fails to properly read wav pipes:

Error: FormatError("data chunk length is not a multiple of sample size")

0xFFFFFFFF should be treated as a special value that means "no length, this is a stream, just read until EOF".

This allows using Hound-based programs in pipeline, like this:

ffmpeg -i some_file.m4a -f wav - | ./program_reads_wav_and_outputs_wav | ffmpeg -i - -y output.mka

@vi
Copy link
Contributor Author

vi commented Mar 17, 2019

possible is to only require W: io::Write on WavWriter, but to add the constraint W: io::Seek to WavWriter::flush() and WavWriter::finalize()

It is one of options. But Drop may be a problem.

Another option may be to split it to higher-level WavWriter and lower-level impl::WavWriter. High-level version automatically calls finialize on Drop and requires Seek;
low-level writer has special function for patching up header (without flusing inner writer) requiring Seek and separate flush function that just flushes writer without seeking, also not finalizing automatically on drop.

vi added a commit to vi/hound that referenced this issue Aug 12, 2019
@cormacrelf
Copy link

I know you've already merged the solution, but FWIW, this is what DAWs do when recording audio, so that if the program crashes, you have something. A while back I saved an hour's worth of live Ableton recordings thanks to this. (Incidentally, Logic couldn't handle the infinite-duration header Ableton wrote and wouldn't import it, so I actually had to hexedit all the files and edit the duration value myself. Also it was AIFF-C, as this technique is not limited to WAV. But it worked!)

ruuda pushed a commit that referenced this issue Sep 25, 2023
Addresses #33.

(cherry picked from commit afa74a0)
@elpiel
Copy link

elpiel commented Mar 16, 2024

This feature would be great!
I believe this is also useful if you want to stream the bytes instead of recording to a file, is it not?

Not sure what's needed for streaming all the bytes, I suppose also updated header would be good for such a stream-like approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants