Skip to content

Commit

Permalink
Merge pull request #62 from martinholters/mh/fixes_0.7
Browse files Browse the repository at this point in the history
Fixes for Julia 0.7
  • Loading branch information
dancasimiro committed Jul 8, 2018
2 parents 90d0cc8 + 53addc4 commit dc23ad1
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 74 deletions.
1 change: 1 addition & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
julia 0.6
FileIO 0.2.0
Compat 0.62
1 change: 1 addition & 0 deletions src/AudioDisplay.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Base.show
using Compat.Base64: base64encode

struct WAVArray{T,N}
Fs::Number
Expand Down
62 changes: 34 additions & 28 deletions src/WAV.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ export WAVChunk, WAVMarker, wav_cue_read, wav_cue_write, wav_info_write, wav_inf
export WAVArray, WAVFormatExtension, WAVFormat
export isextensible, isformat, bits_per_sample
export WAVE_FORMAT_PCM, WAVE_FORMAT_IEEE_FLOAT, WAVE_FORMAT_ALAW, WAVE_FORMAT_MULAW
using Compat: codeunits, findall, nothing, Nothing, undef
import Compat: Libdl
using FileIO

function __init__()
module_dir = dirname(@__FILE__)
if Libdl.find_library(["libpulse-simple"]) != ""
if Libdl.find_library(["libpulse-simple", "libpulse-simple.so.0"]) != ""
include(joinpath(module_dir, "wavplay-pulse.jl"))
elseif Libdl.find_library(["AudioToolbox"],
["/System/Library/Frameworks/AudioToolbox.framework/Versions/A"]) != ""
Expand All @@ -33,7 +35,7 @@ struct WAVFormatExtension
nbits::UInt16 # overrides nbits in WAVFormat type
channel_mask::UInt32
sub_format::Array{UInt8, 1} # 16 byte GUID
WAVFormatExtension() = new(0, 0, Array{UInt8, 1}(0))
WAVFormatExtension() = new(0, 0, UInt8[])
WAVFormatExtension(nb, cm, sb) = new(nb, cm, sb)
end

Expand Down Expand Up @@ -100,7 +102,7 @@ end

function isformat(fmt::WAVFormat, code)
if code != WAVE_FORMAT_EXTENSIBLE && isextensible(fmt)
subtype = Array{UInt8, 1}(0)
subtype = UInt8[]
if code == WAVE_FORMAT_PCM
subtype = KSDATAFORMAT_SUBTYPE_PCM
elseif code == WAVE_FORMAT_IEEE_FLOAT
Expand Down Expand Up @@ -130,7 +132,7 @@ end

function read_header(io::IO)
# check if the given file has a valid RIFF header
riff = Array{UInt8}(4)
riff = Vector{UInt8}(undef, 4)
read!(io, riff)
if riff != b"RIFF"
error("Invalid WAV file: The RIFF header is invalid")
Expand All @@ -139,7 +141,7 @@ function read_header(io::IO)
chunk_size = read_le(io, UInt32)

# check if this is a WAV file
format = Array{UInt8}(4)
format = Vector{UInt8}(undef, 4)
read!(io, format)
if format != b"WAVE"
error("Invalid WAV file: the format is not WAVE")
Expand Down Expand Up @@ -167,12 +169,12 @@ function read_format(io::IO, chunk_size::UInt32)
bytes_per_second = read_le(io, UInt32)
block_align = read_le(io, UInt16)
nbits = read_le(io, UInt16)
ext = Array{UInt8, 1}(0)
ext = UInt8[]
chunk_size -= 16
if chunk_size > 0
extra_bytes_length = read_le(io, UInt16)
if extra_bytes_length == 22
ext = Array{UInt8}(extra_bytes_length)
ext = Vector{UInt8}(undef, extra_bytes_length)
read!(io, ext)
end
end
Expand Down Expand Up @@ -238,9 +240,9 @@ ieee_float_container_type(nbits) = (nbits == 32 ? Float32 : (nbits == 64 ? Float
function read_pcm_samples(io::IO, fmt::WAVFormat, subrange)
nbits = bits_per_sample(fmt)
if isempty(subrange)
return Array{pcm_container_type(nbits), 2}(0, fmt.nchannels)
return Array{pcm_container_type(nbits), 2}(undef, 0, fmt.nchannels)
end
samples = Array{pcm_container_type(nbits), 2}(length(subrange), fmt.nchannels)
samples = Array{pcm_container_type(nbits), 2}(undef, length(subrange), fmt.nchannels)
sample_type = eltype(samples)
nbytes = ceil(Integer, nbits / 8)
bitshift = [0x0, 0x8, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40]
Expand All @@ -251,7 +253,7 @@ function read_pcm_samples(io::IO, fmt::WAVFormat, subrange)
skip(io, convert(UInt, (first(subrange) - 1) * nbytes * fmt.nchannels))
for i = 1:size(samples, 1)
for j = 1:size(samples, 2)
raw_sample = Array{UInt8}(nbytes)
raw_sample = Vector{UInt8}(undef, nbytes)
read!(io, raw_sample)
my_sample = UInt64(0)
for k = 1:nbytes
Expand All @@ -268,10 +270,10 @@ end

function read_ieee_float_samples(io::IO, fmt::WAVFormat, subrange, floatType)
if isempty(subrange)
return Array{floatType, 2}(0, fmt.nchannels)
return Array{floatType, 2}(undef, 0, fmt.nchannels)
end
nblocks = length(subrange)
samples = Array{floatType, 2}(nblocks, fmt.nchannels)
samples = Array{floatType, 2}(undef, nblocks, fmt.nchannels)
nbits = bits_per_sample(fmt)
skip(io, convert(UInt, (first(subrange) - 1) * (nbits / 8) * fmt.nchannels))
for i = 1:nblocks
Expand All @@ -290,10 +292,10 @@ end

function read_companded_samples(io::IO, fmt::WAVFormat, subrange, table)
if isempty(subrange)
return Array{eltype(table), 2}(0, fmt.nchannels)
return Array{eltype(table), 2}(undef, 0, fmt.nchannels)
end
nblocks = length(subrange)
samples = Array{eltype(table), 2}(nblocks, fmt.nchannels)
samples = Array{eltype(table), 2}(undef, nblocks, fmt.nchannels)
skip(io, convert(UInt, (first(subrange) - 1) * fmt.nchannels))
for i = 1:nblocks
for j = 1:fmt.nchannels
Expand Down Expand Up @@ -517,7 +519,11 @@ function read_data(io::IO, chunk_size, fmt::WAVFormat, format, subrange)
# "format" is the format of values, while "fmt" is the WAV file level format
convert_to_double = x -> convert(Array{Float64}, x)

if subrange === Void
if subrange === Nothing
Base.depwarn("`wavread(..., subrange=Nothing)` is deprecated, use `wavread(..., subrange=:)` instead.", :read_data)
subrange = (:)
end
if subrange === (:)
# each block stores fmt.nchannels channels
subrange = 1:convert(UInt, chunk_size / fmt.block_align)
end
Expand Down Expand Up @@ -603,7 +609,7 @@ end
make_range(subrange) = subrange
make_range(subrange::Number) = 1:convert(Int, subrange)

function wavread(io::IO; subrange=Void, format="double")
function wavread(io::IO; subrange=(:), format="double")
chunk_size = read_header(io)
samples = Array{Float64, 1}()
nbits = 0
Expand All @@ -621,7 +627,7 @@ function wavread(io::IO; subrange=Void, format="double")
fmt = WAVFormat()
while chunk_size >= subchunk_header_size
# Read subchunk ID and size
subchunk_id = Array{UInt8}(4)
subchunk_id = Vector{UInt8}(undef, 4)
read!(io, subchunk_id)
subchunk_size = read_le(io, UInt32)
if subchunk_size > chunk_size
Expand All @@ -641,15 +647,15 @@ function wavread(io::IO; subrange=Void, format="double")
end
samples = read_data(io, subchunk_size, fmt, format, make_range(subrange))
else
subchunk_data = Array{UInt8}(subchunk_size)
subchunk_data = Vector{UInt8}(undef, subchunk_size)
read!(io, subchunk_data)
push!(opt, WAVChunk(Symbol(subchunk_id), subchunk_data))
end
end
return samples, sample_rate, nbits, opt
end

function wavread(filename::AbstractString; subrange=Void, format="double")
function wavread(filename::AbstractString; subrange=(:), format="double")
open(filename, "r") do io
wavread(io, subrange=subrange, format=format)
end
Expand Down Expand Up @@ -699,7 +705,7 @@ function wavwrite(samples::AbstractArray, io::IO; Fs=8000, nbits=0, compression=
compression_code = WAVE_FORMAT_EXTENSIBLE
valid_bits_per_sample = nbits
channel_mask = 0
sub_format = Array{UInt8, 1}(0)
sub_format = UInt8[]
if compression == WAVE_FORMAT_PCM
sub_format = KSDATAFORMAT_SUBTYPE_PCM
elseif compression == WAVE_FORMAT_IEEE_FLOAT
Expand Down Expand Up @@ -749,7 +755,7 @@ end
function wavappend(samples::AbstractArray, io::IO)
seekstart(io)
chunk_size = read_header(io)
subchunk_id = Array{UInt8}(4)
subchunk_id = Vector{UInt8}(undef, 4)
read!(io, subchunk_id)
subchunk_size = read_le(io, UInt32)
if subchunk_id != b"fmt "
Expand All @@ -761,18 +767,18 @@ function wavappend(samples::AbstractArray, io::IO)
error("Number of channels do not match")
end

# Compute data length of current chunk to-be-appended.
# Compute data length of current chunk to-be-appended.
data_length = size(samples, 1) * fmt.block_align
# Update `chunksize`: add length of new data.
# Update `chunksize`: add length of new data.
seek(io,4)
write_le(io, convert(UInt32, chunk_size + data_length))
# Get `subchunk2size`.
seek(io,40)
# Get `subchunk2size`.
seek(io, 24 + subchunk_size)
data_length_old = read_le(io, UInt32)
# Update `subchunk2size`: add length of new data.
seek(io,40)
# Update `subchunk2size`: add length of new data.
seek(io, 24 + subchunk_size)
write_le(io, convert(UInt32, data_length_old + data_length))

seekend(io)
write_data(io, fmt, samples)
end
Expand Down
20 changes: 10 additions & 10 deletions src/WAVChunk.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"""
A RIFF chunk.
"""
type WAVChunk
struct WAVChunk
id::Symbol
data::Vector{UInt8}
end

"""
A marker in a .wav file. `start_time` and `duration` are in samples.
"""
type WAVMarker
mutable struct WAVMarker
label::String
start_time::UInt32
duration::UInt32
Expand Down Expand Up @@ -98,8 +98,8 @@ function wav_cue_read(chunks::Vector{WAVChunk})
markers = Dict{UInt32, WAVMarker}()

# See if list and cue chunks are present
list_chunks = chunks[find(c -> c.id == :LIST, chunks)]
cue_chunks = chunks[find(c -> c.id == Symbol("cue "), chunks)]
list_chunks = chunks[findall(c -> c.id == :LIST, chunks)]
cue_chunks = chunks[findall(c -> c.id == Symbol("cue "), chunks)]

for l in list_chunks
read_list(markers, l.data)
Expand Down Expand Up @@ -132,12 +132,12 @@ function write_marker_list(markers::Dict{UInt32, WAVMarker})

# Create all the labl entries
for (cue_id, marker) in markers
labl = [write32(cue_id); Vector{UInt8}(marker.label); 0x0]
labl = [write32(cue_id); codeunits(marker.label); 0x0]

# The note and label entries must have an even number of bytes.
# So, for the null terminated text in the label and note, we add a minimum of
# one null terminator, but if that creates an odd number of bytes in the labl
# or note entry, then add a second null terminator.
# or note entry, then add a second null terminator.
if (length(labl) % 2) == 1
labl = [labl; 0x0]
end
Expand Down Expand Up @@ -171,17 +171,17 @@ function wav_info_write(tags::Dict{Symbol, String})

# Create all the tag entries
for t in keys(tags)
tag = [Vector{UInt8}(tags[t]); 0x0]
tag = [codeunits(tags[t]); 0x0]

# The tag entries must have an even number of bytes.
# So, for the null terminated text in the tag, we add a minimum of
# one null terminator, but if that creates an odd number of bytes in the tag
# or note entry, then add a second null terminator.
# or note entry, then add a second null terminator.
if (length(tag) % 2) == 1
tag = [tag; 0x0]
end

info_data = [info_data; Vector{UInt8}(String(t)); write32(UInt32(length(tag))); tag]
info_data = [info_data; codeunits(String(t)); write32(UInt32(length(tag))); tag]
end
[WAVChunk(:LIST, info_data)]
end
Expand Down Expand Up @@ -215,7 +215,7 @@ https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/RIFF.html#Info
function wav_info_read(chunks::Vector{WAVChunk})
tags = Dict{Symbol, String}()

list_chunks = chunks[find(c -> c.id == :LIST, chunks)]
list_chunks = chunks[findall(c -> c.id == :LIST, chunks)]
for l in list_chunks
list_data = l.data
if list_data[1:4] == b"INFO"
Expand Down
30 changes: 16 additions & 14 deletions src/wavplay-audioqueue.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# -*- mode: julia; -*-
module WAVPlay
import WAV.wavplay
import ..wavplay

using Compat: Cvoid, undef

const OSStatus = Int32
const CFTypeRef = Ptr{Void}
const CFRunLoopRef = Ptr{Void}
const CFStringRef = Ptr{Void}
const AudioQueueRef = Ptr{Void}
const CFTypeRef = Ptr{Cvoid}
const CFRunLoopRef = Ptr{Cvoid}
const CFStringRef = Ptr{Cvoid}
const AudioQueueRef = Ptr{Cvoid}

# format IDs
const kAudioFormatLinearPCM = # "lpcm"
Expand Down Expand Up @@ -61,9 +63,9 @@ end
# Apple Core Audio Type
mutable struct AudioQueueBuffer
mAudioDataBytesCapacity::UInt32
mAudioData::Ptr{Void}
mAudioData::Ptr{Cvoid}
mAudioDataByteSize::UInt32
mUserData::Ptr{Void}
mUserData::Ptr{Cvoid}
mPacketDescriptionCapacity::UInt32
mPacketDescription::Ptr{AudioStreamPacketDescription}
mPacketDescriptionCount::UInt32
Expand All @@ -78,8 +80,8 @@ const AudioToolbox =
"/System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox"

CFRunLoopGetCurrent() = ccall((:CFRunLoopGetCurrent, CoreFoundation), CFRunLoopRef, ())
CFRunLoopRun() = ccall((:CFRunLoopRun, CoreFoundation), Void, ())
CFRunLoopStop(rl) = ccall((:CFRunLoopStop, CoreFoundation), Void, (CFRunLoopRef, ), rl)
CFRunLoopRun() = ccall((:CFRunLoopRun, CoreFoundation), Cvoid, ())
CFRunLoopStop(rl) = ccall((:CFRunLoopStop, CoreFoundation), Cvoid, (CFRunLoopRef, ), rl)
getCoreFoundationRunLoopDefaultMode() =
unsafe_load(cglobal((:kCFRunLoopDefaultMode, CoreFoundation), CFStringRef))

Expand Down Expand Up @@ -146,7 +148,7 @@ end
# audio queue buffer structure, AudioQueueBuffer, is initially set to 0.
# @result An OSStatus result code.
function AudioQueueAllocateBuffer(aq)
newBuffer = Array{AudioQueueBufferRef, 1}(1)
newBuffer = Array{AudioQueueBufferRef, 1}(undef, 1)
result =
ccall((:AudioQueueAllocateBuffer, AudioToolbox), OSStatus,
(AudioQueueRef, UInt32, Ptr{AudioQueueBufferRef}),
Expand Down Expand Up @@ -175,7 +177,7 @@ function AudioQueueEnqueueBuffer(aq, bufPtr, data)
unsafe_store!(bufPtr, buffer)
result = ccall((:AudioQueueEnqueueBuffer, AudioToolbox),
OSStatus,
(AudioQueueRef, AudioQueueBufferRef, UInt32, Ptr{Void}),
(AudioQueueRef, AudioQueueBufferRef, UInt32, Ptr{Cvoid}),
aq, bufPtr, 0, C_NULL)
if result != 0
error("AudioQueueEnqueueBuffer failed with $result")
Expand Down Expand Up @@ -263,12 +265,12 @@ function AudioQueueNewOutput(format::AudioStreamBasicDescription, userData::Audi
userData.runLoop = runLoop
runLoopMode = getCoreFoundationRunLoopDefaultMode()

newAudioQueue = Array{AudioQueueRef, 1}(1)
cCallbackProc = cfunction(playCallback, Void,
newAudioQueue = Array{AudioQueueRef, 1}(undef, 1)
cCallbackProc = cfunction(playCallback, Cvoid,
(Ptr{AudioQueueData}, AudioQueueRef, AudioQueueBufferRef))
result =
ccall((:AudioQueueNewOutput, AudioToolbox), OSStatus,
(Ptr{AudioStreamBasicDescription}, Ptr{Void}, Ptr{AudioQueueData}, CFRunLoopRef, CFStringRef, UInt32, Ptr{AudioQueueRef}),
(Ptr{AudioStreamBasicDescription}, Ptr{Cvoid}, Ptr{AudioQueueData}, CFRunLoopRef, CFStringRef, UInt32, Ptr{AudioQueueRef}),
Ref(format), cCallbackProc, Ref(userData), runLoop, runLoopMode, 0, newAudioQueue)
if result != 0
error("AudioQueueNewOutput failed with $result")
Expand Down
Loading

0 comments on commit dc23ad1

Please sign in to comment.