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

wavappend() doesn't update header in certain case #60

Closed
beyondvoid opened this issue Jun 6, 2018 · 8 comments
Closed

wavappend() doesn't update header in certain case #60

beyondvoid opened this issue Jun 6, 2018 · 8 comments

Comments

@beyondvoid
Copy link

Hi, everyone.

It seems that the function WAV.wavappend doesn't update the header information in the following case:

import WAV 
x1 = rand(16000)
x2 = rand(16000)
WAV.wavwrite(x1, "test.wav", Fs=16000, nbits=16, compression=WAV.WAVE_FORMAT_PCM)
WAV.wavappend(x2, "test.wav")

The code above correctly appends the data; however, when opening the file with, e.g., Audacity, the program reads the first part of the wave file containing x1 only. I think that the header is not updated correctly. It might have something to do with the compression.

By the way: I'm using Julia-0.6.3 (Windows & Linux).

@beyondvoid
Copy link
Author

By the way: reading out the field subchunk2size by using

header = read("test.wav", 46)
sum(header[41:44] .* (256.^(0:3)))

yields 32000, which is wrong, since it should be 64000. (Note: subchunk2size equals number_samples * number_channels * bits_per_sample / 8).

@beyondvoid
Copy link
Author

I just figured out that the value corresponding to the field chunksize is correct; however, the value corresponding to subchunk2size is wrong. My current workaround is as follows:

# Note: `number_samples` and `path_file` is given. 

# Read header. 
file_stream = open(path_file, "r+")
header = read(file_stream, 46)

# Find characters `data` to determine length (44-bytes or 46-bytes) of header. 
# Hex-string below corresponds to the characters `data`.            
range_matched_sequence = search(header, [0x64, 0x61, 0x74, 0x61])
if !isempty(range_matched_sequence)
    indices_data_size = range_matched_sequence + 4;
    if ==(maximum(indices_data_size), 46)
        warn("File features 46-byte header.")
    end
else
    error("Invalid file header.")
end

# Get value that corresponds to field `blockalign`. 
block_align = sum(header[33:34] .* (256.^(0:1)))
if ~isinteger(block_align)
    error("Corrupted file: non-integer block align.")
end

# Update header. 
header[indices_data_size] = reverse(hex2bytes(hex(number_samples*block_align, 8)))

# Overwrite file's header by updated header. 
seekstart(file_stream)
write(file_stream, header)
close(file_stream)

This way I avoid reading and writing the whole file.

@beyondvoid
Copy link
Author

And by the way: Do you assume 44-byte and/or 46-byte header files?

@beyondvoid
Copy link
Author

I skimmed through the code and realized that wavappend (or even the whole WAV-package) only supports 44-byte headers. (Please correct me if I'm wrong.) If this is the case, I would suggest that the package should either

  1. throw an error if it appends to a wave file that features a 46-byte header or
  2. converts the 46-byte header into a 44-byte header as follows:
# `header` is an array containing the first 46 bytes of the wave file
if ==(header[17], 0x12)
    warning("Converting 46-byte header into 44-byte header.")
    header[17] = 0x10
    deleteat!(header, [37,38])
end

@beyondvoid
Copy link
Author

Hi, everyone. I've found and fixed the bug related to the aforementioned problem. Please go through my pull-request in order to figure out what I've changed.

@dancasimiro
Copy link
Owner

Thanks @beyondvoid

It’s been a while since I wrote the header code. I’ll take a look and get back to you.

@beyondvoid
Copy link
Author

beyondvoid commented Jun 9, 2018

Hi, @dancasimiro. Thanks for taking a look. If you are interested you can find detailed information on the header at https://soundfile.sapp.org/doc/WaveFormat/.

dancasimiro added a commit that referenced this issue Jun 15, 2018
Fixed bug #60 related to updating header when using 'wavappend()'
@dancasimiro
Copy link
Owner

Fixed by pull request #61.

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

2 participants