Comments (7)
Thanks for the suggestion! This is something I've briefly thought about before, but never implemented because it hasn't scratched a personal itch. It seems like a reasonable feature, but would need to update the Writer
constructor signature to allow indicating that it should be in append mode. Is there a particular use case where this would be helpful for you?
from wavefile.
If an exception occurs while writing, before Writer#close is called, I think a wave file would then be left in a non-usable state since the RIFF header wouldn't have been finalized yet. True? So, as a user I would like to be sure that the data I've written so far is safe and usable in the event of an exception.
I think a simple way to implement this is to close the file and open it in append mode. Then the Writer class could be set up to close/reopen on its own at a set interval (every N samples, or something). But at least giving the user the option to close and reopen in append mode would be a step in the right direction.
There may be other convenience reasons for wanting to append.
from wavefile.
I hadn't been thinking about the point you brought up of dealing with exceptions that occur when writing a file using a block. For example, in this code:
Writer.new("error.wav", format) do |writer|
writer.write(buffer)
x = 1 / 0
end
the resulting Wave file will not be valid, and there's no way (in the current version of WaveFile) to catch the ZeroDivisionError
and close the file.
I think this would be simple to fix. In Writer.new
, this code:
if block_given?
yield(self)
close
end
could be replaced with this code:
if block_given?
begin
yield(self)
ensure
close
end
end
Which would ensure that the header gets written even if an exception occurs.
While the wave file would be playable, you wouldn't be able to go back and add more data to the file. Your suggestion of being able to open a file in append mode would resolve that.
from wavefile.
I opened a separate bug for the issue of no header being written when an exception occurs. If you are interested in fixing that bug and adding tests just assign the issue to yourself. If not, no problem, I can do it.
One other thought about adding support for appending is that the Writer.samples_written
attribute could become misleading. That is, you might want a distinction between the number of samples in the entire file, and the number of samples written since the file was opened. When opened in regular mode, these would be the same. Something like Writer.total_samples
and Writer.samples_written
.
from wavefile.
I added support for append mode over at my fork: https://github.com/jamestunnell/wavefile
Included in the changes, I added a 'total_sample_frames' method like you suggested. Though now that I think about it, I suppose for naming consistency it could also be called 'sample_frames_total'. Maybe a 'sample_frames_existing' method would be desirable too?
Would you take a look at the changes? Any feedback?
from wavefile.
Thanks for the code! Unfortunately, while I was looking at it I realized a few basic problems with appending data to a Wave file. The issues revolve around the fact that a Wave file is composed of "chunks" which are not guaranteed to be in a particular order.
First, the data chunk is not guaranteed to be the last chunk in the file. If it's not, then appending would write the data in the wrong place. I think it's sensible for the data chunk to be last, and assume that that is the case for most Wave files (including all files written by this gem), but I'm not sure how safe of an assumption that is universally.
Another issue is that when the file is closed, the act of rewriting the header could cause existing chunks to be overwritten. For example, this gem always writes a format chunk, optionally followed by a fact chunk, and then a data chunk. If the existing file has other chunks between the format and data chunks then they will be overwritten and the file will likely be corrupted.
An implementation of this feature would need to be aware of the chunks in the file, and deal with them so that they all end up in the output file. In addition, the data in certain chunks (such as the fact chunk) depends on the amount of data in the data chunk, and they would have to be updated accordingly when the file is closed.
Sorry for not realizing this earlier. This feature seems more complicated than it did on the surface. I think this is something that would have to be thought about more before being implemented.
from wavefile.
Yeah, I see your points and I agree.
from wavefile.
Related Issues (20)
- Possible bug when no block is given to the writer? HOT 2
- No high-level duration info HOT 2
- Example here - https://github.com/jstrait/wavefile/wiki/WaveFile-Tutorial#copying-a-wave-file-to-different-format working correctly? HOT 5
- fyi: ruby-wavefile now packaged for Debian HOT 1
- support reading from a file or stream HOT 5
- Duration does not override equality HOT 2
- UnsupportedFormatError HOT 8
- Method to obtain markers/cue points HOT 6
- each_buffer causes ReaderClosedError HOT 3
- Reference for older methods HOT 4
- examples: how create reverse file? HOT 2
- Mix 2 wav files. HOT 2
- Rewind the IO object HOT 4
- Format Chunks With Extra Bytes at the End Sometimes Cause `InvalidFormatError` to be Raised HOT 1
- `Reader` instances can be created for WAVE_FORMAT_EXTENSIBLE files that have an incomplete/missing format chunk extension HOT 1
- Bufer from bytes & mulaw HOT 2
- WaveFile::Reader doesn't work with pipe IO HOT 2
- Sample Data Can't Be Read From a WAVE_FORMAT_EXTENSIBLE File With an Oversized Format Chunk Extension HOT 1
- How i can play file HOT 1
- Misleading error message if "fmt " chunk extension is too large to fit into chunk HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wavefile.