Skip to content
Browse files

Soundfile.{read,write}{,f}_{short,int,float,double}({Numeric,Sound})

darcs-hash:20051119034702-28bda-6fe568a45471bef37266b720e3efa2cad3ebe7b0.gz
  • Loading branch information...
1 parent d4f3adf commit 42bf660f95fb9a14035484376b809d1098cba6db @fugalh committed
Showing with 86 additions and 8 deletions.
  1. +5 −1 Rakefile
  2. +6 −0 lib/audio.rb
  3. +70 −4 lib/sndfile.rb
  4. +5 −3 test/test_sndfile.rb
View
6 Rakefile
@@ -7,10 +7,14 @@ file 'ext/sndfile/sndfile_wrap.c' => ['ext/sndfile/sndfile.i'] do
sh 'cd ext/sndfile; swig -ruby sndfile.i'
end
-task :sndfile => ['ext/sndfile/sndfile_wrap.c'] do
+task :sndfile => ['ext/sndfile/sndfile_wrap.c', 'ext/sndfile/Makefile'] do
sh 'make -C ext/sndfile'
end
+file 'ext/sndfile/Makefile' => ['ext/sndfile/extconf.rb'] do |t|
+ sh "ruby -C ext/sndfile extconf.rb"
+end
+
require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs += ['ext/sndfile']
View
6 lib/audio.rb
@@ -110,6 +110,12 @@ def self.deinterleave(narray,channels)
s.interleaved = narray
s
end
+ def deinterleave(channels)
+ self.class.deinterleave(self,channels)
+ end
+ def deinterleave!(channels)
+ self[] = deinterleave(channels)
+ end
%w{char short long float double}.each_with_index do |t,i|
eval "def self.#{t}(frames,channels=1); self.new(#{i+1},frames,channels); end"
View
74 lib/sndfile.rb
@@ -8,7 +8,7 @@ module Audio
# require 'narray'
#
# sf = Audio::Soundfile.open('chunky_bacon.wav')
- # na = Audio::Sound.float(sf.info.frames, sf.info.channels)
+ # na = Audio::Sound.float(sf.frames, sf.channels)
# sf.read_float(na)
# sf.close
#
@@ -28,11 +28,10 @@ module Audio
# Exceptions to this pattern are documented below.
#
# Constants are accessed as <tt>Soundfile::SF_FORMAT_WAV</tt>
- #
- # TODO read/write functions with Sound objects.
class Soundfile
# SF_INFO
attr :info
+ attr_reader :mode
# mode:: One of %w{r w rw}
# info:: Instance of SF_INFO or nil
@@ -41,8 +40,8 @@ def initialize(path, mode='r', info=nil)
info = SF_INFO.new
end
+ modes = {:r => SFM_READ, :w => SFM_WRITE, :rw => SFM_RDWR}
unless Numeric === mode
- modes = {:r => SFM_READ, :w => SFM_WRITE, :rw => SFM_RDWR}
mode = modes[mode.to_sym]
end
unless [SFM_READ, SFM_WRITE, SFM_RDWR].include? mode
@@ -52,6 +51,7 @@ def initialize(path, mode='r', info=nil)
sf = Sndfile.sf_open(path.to_s, mode, info)
@sf = sf
@info = info
+ @mode = modes.invert[mode]
if block_given?
yield self
self.close
@@ -62,6 +62,43 @@ class << self
alias_method :open, :new
end
+ def frames=(o)
+ @info.frames=(o)
+ end
+ def samplerate=(o)
+ @info.samplerate=(o)
+ end
+ def channels=(o)
+ @info.channels=(o)
+ end
+ def format=(o)
+ @info.format=(o)
+ end
+ def sections=(o)
+ @info.sections=(o)
+ end
+ def seekable=(o)
+ @info.seekable=(o)
+ end
+ def frames
+ @info.frames
+ end
+ def samplerate
+ @info.samplerate
+ end
+ def channels
+ @info.channels
+ end
+ def format
+ @info.format
+ end
+ def sections
+ @info.sections
+ end
+ def seekable
+ @info.seekable
+ end
+
# The following are equivalent:
# sf_format_check(info) /* C */
# sf.format_check # ruby
@@ -81,6 +118,35 @@ def write(na)
self.send sym, na
end
+ %w{read readf}.each do |r|
+ %w{short int float double}.each do |t|
+ tc = Audio::Sound::TYPES.index(t.to_sym)
+ c = ', channels' if r == 'readf'
+ cmd = "#{r}_#{t}"
+ eval <<-EOF
+ def #{cmd}(arg)
+ na = NArray.new(#{tc}, arg#{c})
+ n = Sndfile.sf_#{cmd}(@sf, na)
+ Sound.deinterleave(na, channels)
+ else
+ n = Sndfile.sf_#{cmd}(@sf, na)
+ na.deinterleave!
+ n
+ end
+ EOF
+ end
+ end
+
+ %w{write writef}.each do |w|
+ %w{short int float double}.each do |t|
+ cmd = "#{w}_#{t}"
+ eval <<-EOF
+ def #{cmd}(sound)
+ Sndfile.sf_#{cmd}(sound.interleave)
+ end
+ EOF
+ end
+ end
def method_missing(name, *args) #:nodoc:
begin
View
8 test/test_sndfile.rb
@@ -139,9 +139,11 @@ def test_rubization
sf.close
Audio::Soundfile.open(TEST_WAV) do |sf|
- a = NArray.sfloat(100)
- n = sf.read_float(a)
- assert n <= a.size
+ a = sf.read_float(100)
+ assert_instance_of Sound, a
+ assert a.size <= 100
+ assert_equal sf.channels, a.channels
+
n = sf.read(a)
assert n <= a.size
end

0 comments on commit 42bf660

Please sign in to comment.
Something went wrong with that request. Please try again.