sndfile 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +43 -0
- data/Gemfile +3 -0
- data/README.md +45 -0
- data/Rakefile +17 -0
- data/lib/gsl-ng/matrix.rb +38 -0
- data/lib/sndfile.rb +9 -0
- data/lib/sndfile/enums.rb +181 -0
- data/lib/sndfile/error.rb +8 -0
- data/lib/sndfile/file.rb +202 -0
- data/lib/sndfile/sndfile_api.rb +98 -0
- data/lib/sndfile/version.rb +3 -0
- data/sndfile.gemspec +26 -0
- data/spec/file_spec.rb +20 -0
- data/spec/inputs/ComputerMagic.wav +0 -0
- data/spec/inputs/Flute3.wav +0 -0
- data/spec/integration_spec.rb +73 -0
- data/spec/refs/ref-copy.wav +0 -0
- data/spec/refs/ref-half.wav +0 -0
- data/spec/refs/ref-mix.wav +0 -0
- data/spec/spec_helper.rb +33 -0
- metadata +153 -0
data/.gitignore
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
*.gem
|
2
|
+
.bundle
|
3
|
+
Gemfile.lock
|
4
|
+
pkg/*
|
5
|
+
spec/outputs/*
|
6
|
+
|
7
|
+
# rcov generated
|
8
|
+
coverage
|
9
|
+
|
10
|
+
# rdoc generated
|
11
|
+
rdoc
|
12
|
+
|
13
|
+
# yard generated
|
14
|
+
doc
|
15
|
+
.yardoc
|
16
|
+
|
17
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
18
|
+
#
|
19
|
+
# * Create a file at ~/.gitignore
|
20
|
+
# * Include files you want ignored
|
21
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
22
|
+
#
|
23
|
+
# After doing this, these files will be ignored in all your git projects,
|
24
|
+
# saving you from having to 'pollute' every project you touch with them
|
25
|
+
#
|
26
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
27
|
+
#
|
28
|
+
# For MacOS:
|
29
|
+
#
|
30
|
+
#.DS_Store
|
31
|
+
#
|
32
|
+
# For TextMate
|
33
|
+
#*.tmproj
|
34
|
+
#tmtags
|
35
|
+
#
|
36
|
+
# For emacs:
|
37
|
+
#*~
|
38
|
+
#\#*
|
39
|
+
#.\#*
|
40
|
+
#
|
41
|
+
# For vim:
|
42
|
+
#*.swp
|
43
|
+
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
Libsndfile for Ruby
|
2
|
+
-------------
|
3
|
+
|
4
|
+
*sndfile* provides a fast and easy way to read, process, and write audio
|
5
|
+
file data. It wraps the [libsndfile](http://www.mega-nerd.com/libsndfile/)
|
6
|
+
C library via [FFI](http://github.com/ffi/ffi), reading & writing the
|
7
|
+
sample data as a [GSLng](https://github.com/v01d/ruby-gsl-ng) matrix.
|
8
|
+
|
9
|
+
The author has (so far) fleshed out only the parts needed for his own projects. Please do fork this project and contribute to it.
|
10
|
+
|
11
|
+
Libsndfile?
|
12
|
+
===========
|
13
|
+
"Libsndfile is a C library for reading and writing files containing sampled sound (such as MS Windows WAV and the Apple/SGI AIFF format) through one standard library interface. It is released in source code format under the Gnu Lesser General Public License."
|
14
|
+
|
15
|
+
|
16
|
+
Installation
|
17
|
+
============
|
18
|
+
|
19
|
+
To use this Ruby library, you must have [libsndfile](http://www.mega-nerd.com/libsndfile/) and [GSL](http://www.gnu.org/software/gsl/) on your machine. You can install
|
20
|
+
them via apt-get (linux) or homebrew (OS X) or download them directly from their websites.
|
21
|
+
|
22
|
+
That being said:
|
23
|
+
|
24
|
+
gem install sndfile
|
25
|
+
|
26
|
+
or, in a Gemfile
|
27
|
+
|
28
|
+
gem "sndfile-ruby", :require => "sndfile"
|
29
|
+
|
30
|
+
Usage
|
31
|
+
=====
|
32
|
+
Here's a simple example, that reads an arbitrary source file and produces a WAV file at half the volume:
|
33
|
+
|
34
|
+
fin = Sndfile::File.new(inpath)
|
35
|
+
Sndfile::File.open(outpath, :mode => :WRITE, :format => :WAV, :encoding => :PCM_16, :channels => fin.channels, :samplerate => fin.samplerate) do |fout|
|
36
|
+
while data = fin.read(10000)
|
37
|
+
fout.write(data * 0.5)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
See the [RDOC](http://rubydoc.info/gems/sndfile) for more info.
|
42
|
+
|
43
|
+
|
44
|
+
History
|
45
|
+
=======
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rdoc/task'
|
4
|
+
Rake::RDocTask.new do |rdoc|
|
5
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
6
|
+
|
7
|
+
rdoc.main = 'README.rdoc'
|
8
|
+
rdoc.rdoc_dir = 'rdoc'
|
9
|
+
rdoc.title = "sndfile #{version}"
|
10
|
+
rdoc.rdoc_files.include('README*')
|
11
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
16
|
+
spec.rspec_opts = '-Ispec'
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# GSLng::Matrix is extended with two aliases:
|
2
|
+
#
|
3
|
+
# GSLng::Matrix#frames, which is an alias for GSLng::Matrix#m and GSLng::Matrix#height
|
4
|
+
#
|
5
|
+
# GSLng::Matrix#channels, which is an alias for GSLng::Matrix#n and GSLng::Matrix#width
|
6
|
+
#
|
7
|
+
class GSLng::Matrix
|
8
|
+
|
9
|
+
|
10
|
+
# @method frames
|
11
|
+
# frames is an alias for GSLng::Matrix#m and GSLng::Matrix#height
|
12
|
+
#
|
13
|
+
alias :frames :m
|
14
|
+
|
15
|
+
|
16
|
+
# @method channels
|
17
|
+
# channels is an alias for GSLng::Matrix#n and GSLng::Matrix#width
|
18
|
+
#
|
19
|
+
alias :channels :n
|
20
|
+
|
21
|
+
unless instance_methods.include? :data_ptr
|
22
|
+
|
23
|
+
class GSL_matrix < FFI::Struct # :nodoc:
|
24
|
+
layout :size1, :size_t,
|
25
|
+
:size2, :size_t,
|
26
|
+
:tda, :size_t,
|
27
|
+
:data, :pointer,
|
28
|
+
:block, :pointer,
|
29
|
+
:owner, :int
|
30
|
+
end
|
31
|
+
|
32
|
+
def data_ptr # :nodoc:
|
33
|
+
GSL_matrix.new(ptr)[:data]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/sndfile.rb
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
module Sndfile # :nodoc: all
|
2
|
+
module Enums
|
3
|
+
extend FFI::Library
|
4
|
+
|
5
|
+
# Error Codes
|
6
|
+
ErrorCode = enum(
|
7
|
+
:SF_ERR_NO_ERROR, 0,
|
8
|
+
:SF_ERR_UNRECOGNISED_FORMAT, 1,
|
9
|
+
:SF_ERR_SYSTEM, 2,
|
10
|
+
:SF_ERR_MALFORMED_FILE, 3,
|
11
|
+
:SF_ERR_UNSUPPORTED_ENCODING, 4,
|
12
|
+
)
|
13
|
+
|
14
|
+
|
15
|
+
# Modes for opening files.
|
16
|
+
FileMode = enum(
|
17
|
+
:READ, 0x10,
|
18
|
+
:WRITE, 0x20,
|
19
|
+
:RDWR, 0x30,
|
20
|
+
)
|
21
|
+
|
22
|
+
# Major formats.
|
23
|
+
FORMAT_MASK = 0x0FFF0000
|
24
|
+
Format = enum(
|
25
|
+
:WAV, 0x010000, # Microsoft WAV format (little endian).
|
26
|
+
:AIFF, 0x020000, # Apple/SGI AIFF format (big endian).
|
27
|
+
:AU, 0x030000, # Sun/NeXT AU format (big endian).
|
28
|
+
:RAW, 0x040000, # RAW PCM data.
|
29
|
+
:PAF, 0x050000, # Ensoniq PARIS file format.
|
30
|
+
:SVX, 0x060000, # Amiga IFF / SVX8 / SV16 format.
|
31
|
+
:NIST, 0x070000, # Sphere NIST format.
|
32
|
+
:VOC, 0x080000, # VOC files.
|
33
|
+
:IRCAM, 0x0A0000, # Berkeley/IRCAM/CARL
|
34
|
+
:W64, 0x0B0000, # Sonic Foundry's 64 bit RIFF/WAV
|
35
|
+
:MAT4, 0x0C0000, # Matlab (tm) V4.2 / GNU Octave 2.0
|
36
|
+
:MAT5, 0x0D0000, # Matlab (tm) V5.0 / GNU Octave 2.1
|
37
|
+
:PVF, 0x0E0000, # Portable Voice Format
|
38
|
+
:XI, 0x0F0000, # Fasttracker 2 Extended Instrument
|
39
|
+
:HTK, 0x100000, # HMM Tool Kit format
|
40
|
+
:SDS, 0x110000, # Midi Sample Dump Standard
|
41
|
+
:AVR, 0x120000, # Audio Visual Research
|
42
|
+
:WAVEX, 0x130000, # MS WAVE with WAVEFORMATEX
|
43
|
+
:SD2, 0x160000, # Sound Designer 2
|
44
|
+
:FLAC, 0x170000, # FLAC lossless file format
|
45
|
+
:CAF, 0x180000, # Core Audio File format
|
46
|
+
:WVE, 0x190000, # Psion WVE format
|
47
|
+
:OGG, 0x200000, # Xiph OGG container
|
48
|
+
:MPC2K, 0x210000, # Akai MPC 2000 sampler
|
49
|
+
:RF64, 0x220000, # RF64 WAV file
|
50
|
+
)
|
51
|
+
|
52
|
+
# Subtypes from here on.
|
53
|
+
ENCODING_MASK = 0x0000FFFF
|
54
|
+
Encoding = enum(
|
55
|
+
:PCM_S8, 0x0001, # Signed 8 bit data
|
56
|
+
:PCM_16, 0x0002, # Signed 16 bit data
|
57
|
+
:PCM_24, 0x0003, # Signed 24 bit data
|
58
|
+
:PCM_32, 0x0004, # Signed 32 bit data
|
59
|
+
|
60
|
+
:PCM_U8, 0x0005, # Unsigned 8 bit data (WAV and RAW only)
|
61
|
+
|
62
|
+
:FLOAT, 0x0006, # 32 bit float data
|
63
|
+
:DOUBLE, 0x0007, # 64 bit float data
|
64
|
+
|
65
|
+
:ULAW, 0x0010, # U-Law encoded.
|
66
|
+
:ALAW, 0x0011, # A-Law encoded.
|
67
|
+
:IMA_ADPCM, 0x0012, # IMA ADPCM.
|
68
|
+
:MS_ADPCM, 0x0013, # Microsoft ADPCM.
|
69
|
+
|
70
|
+
:GSM610, 0x0020, # GSM 6.10 encoding.
|
71
|
+
:VOX_ADPCM, 0x0021, # Oki Dialogic ADPCM encoding.
|
72
|
+
|
73
|
+
:G721_32, 0x0030, # 32kbs G721 ADPCM encoding.
|
74
|
+
:G723_24, 0x0031, # 24kbs G723 ADPCM encoding.
|
75
|
+
:G723_40, 0x0032, # 40kbs G723 ADPCM encoding.
|
76
|
+
|
77
|
+
:DWVW_12, 0x0040, # 12 bit Delta Width Variable Word encoding.
|
78
|
+
:DWVW_16, 0x0041, # 16 bit Delta Width Variable Word encoding.
|
79
|
+
:DWVW_24, 0x0042, # 24 bit Delta Width Variable Word encoding.
|
80
|
+
:DWVW_N, 0x0043, # N bit Delta Width Variable Word encoding.
|
81
|
+
|
82
|
+
:DPCM_8, 0x0050, # 8 bit differential PCM (XI only)
|
83
|
+
:DPCM_16, 0x0051, # 16 bit differential PCM (XI only)
|
84
|
+
|
85
|
+
:VORBIS, 0x0060, # Xiph Vorbis encoding.
|
86
|
+
)
|
87
|
+
|
88
|
+
# Endian-ness options.
|
89
|
+
ENDIAN_MASK = 0x30000000
|
90
|
+
Endian = enum(
|
91
|
+
:FILE, 0x00000000, # Default file endian-ness.
|
92
|
+
:LITTLE, 0x10000000, # Force little endian-ness.
|
93
|
+
:BIG, 0x20000000, # Force big endian-ness.
|
94
|
+
:CPU, 0x30000000, # Force CPU endian-ness.
|
95
|
+
)
|
96
|
+
|
97
|
+
# Command numbers for sf_command
|
98
|
+
Command = enum(
|
99
|
+
:SFC_GET_LIB_VERSION, 0x1000,
|
100
|
+
:SFC_GET_LOG_INFO, 0x1001,
|
101
|
+
:SFC_GET_CURRENT_SF_INFO, 0x1002,
|
102
|
+
|
103
|
+
|
104
|
+
:SFC_GET_NORM_DOUBLE, 0x1010,
|
105
|
+
:SFC_GET_NORM_FLOAT, 0x1011,
|
106
|
+
:SFC_SET_NORM_DOUBLE, 0x1012,
|
107
|
+
:SFC_SET_NORM_FLOAT, 0x1013,
|
108
|
+
:SFC_SET_SCALE_FLOAT_INT_READ, 0x1014,
|
109
|
+
:SFC_SET_SCALE_INT_FLOAT_WRITE, 0x1015,
|
110
|
+
|
111
|
+
:SFC_GET_SIMPLE_FORMAT_COUNT, 0x1020,
|
112
|
+
:SFC_GET_SIMPLE_FORMAT, 0x1021,
|
113
|
+
|
114
|
+
:SFC_GET_FORMAT_INFO, 0x1028,
|
115
|
+
|
116
|
+
:SFC_GET_FORMAT_MAJOR_COUNT, 0x1030,
|
117
|
+
:SFC_GET_FORMAT_MAJOR, 0x1031,
|
118
|
+
:SFC_GET_FORMAT_SUBTYPE_COUNT, 0x1032,
|
119
|
+
:SFC_GET_FORMAT_SUBTYPE, 0x1033,
|
120
|
+
|
121
|
+
:SFC_CALC_SIGNAL_MAX, 0x1040,
|
122
|
+
:SFC_CALC_NORM_SIGNAL_MAX, 0x1041,
|
123
|
+
:SFC_CALC_MAX_ALL_CHANNELS, 0x1042,
|
124
|
+
:SFC_CALC_NORM_MAX_ALL_CHANNELS, 0x1043,
|
125
|
+
:SFC_GET_SIGNAL_MAX, 0x1044,
|
126
|
+
:SFC_GET_MAX_ALL_CHANNELS, 0x1045,
|
127
|
+
|
128
|
+
:SFC_SET_ADD_PEAK_CHUNK, 0x1050,
|
129
|
+
:SFC_SET_ADD_HEADER_PAD_CHUNK, 0x1051,
|
130
|
+
|
131
|
+
:SFC_UPDATE_HEADER_NOW, 0x1060,
|
132
|
+
:SFC_SET_UPDATE_HEADER_AUTO, 0x1061,
|
133
|
+
|
134
|
+
:SFC_FILE_TRUNCATE, 0x1080,
|
135
|
+
|
136
|
+
:SFC_SET_RAW_START_OFFSET, 0x1090,
|
137
|
+
|
138
|
+
:SFC_SET_DITHER_ON_WRITE, 0x10A0,
|
139
|
+
:SFC_SET_DITHER_ON_READ, 0x10A1,
|
140
|
+
|
141
|
+
:SFC_GET_DITHER_INFO_COUNT, 0x10A2,
|
142
|
+
:SFC_GET_DITHER_INFO, 0x10A3,
|
143
|
+
|
144
|
+
:SFC_GET_EMBED_FILE_INFO, 0x10B0,
|
145
|
+
|
146
|
+
:SFC_SET_CLIPPING, 0x10C0,
|
147
|
+
:SFC_GET_CLIPPING, 0x10C1,
|
148
|
+
|
149
|
+
:SFC_GET_INSTRUMENT, 0x10D0,
|
150
|
+
:SFC_SET_INSTRUMENT, 0x10D1,
|
151
|
+
|
152
|
+
:SFC_GET_LOOP_INFO, 0x10E0,
|
153
|
+
|
154
|
+
:SFC_GET_BROADCAST_INFO, 0x10F0,
|
155
|
+
:SFC_SET_BROADCAST_INFO, 0x10F1,
|
156
|
+
|
157
|
+
:SFC_GET_CHANNEL_MAP_INFO, 0x1100,
|
158
|
+
:SFC_SET_CHANNEL_MAP_INFO, 0x1101,
|
159
|
+
|
160
|
+
:SFC_RAW_DATA_NEEDS_ENDSWAP, 0x1110,
|
161
|
+
|
162
|
+
# Support for Wavex Ambisonics Format
|
163
|
+
:SFC_WAVEX_SET_AMBISONIC, 0x1200,
|
164
|
+
:SFC_WAVEX_GET_AMBISONIC, 0x1201,
|
165
|
+
|
166
|
+
:SFC_SET_VBR_ENCODING_QUALITY, 0x1300,
|
167
|
+
|
168
|
+
# Following commands for testing only.
|
169
|
+
:SFC_TEST_IEEE_FLOAT_REPLACE, 0x6001,
|
170
|
+
|
171
|
+
##
|
172
|
+
## :SFC_SET_ADD_* values are deprecated and will disappear at some
|
173
|
+
## time in the future. They are guaranteed to be here up to and
|
174
|
+
## including version 1.0.8 to avoid breakage of existng software.
|
175
|
+
## They currently do nothing and will continue to do nothing.
|
176
|
+
##
|
177
|
+
:SFC_SET_ADD_DITHER_ON_WRITE, 0x1070,
|
178
|
+
:SFC_SET_ADD_DITHER_ON_READ, 0x1071
|
179
|
+
)
|
180
|
+
end
|
181
|
+
end
|
data/lib/sndfile/file.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
module Sndfile
|
2
|
+
|
3
|
+
class File
|
4
|
+
include SndfileApi
|
5
|
+
|
6
|
+
#
|
7
|
+
# Without a block, this is the same as File.new(path, opts).
|
8
|
+
# With a block, yields the File object to the block and ensures that
|
9
|
+
# File#close is then called .
|
10
|
+
#
|
11
|
+
def self.open(path, opts={})
|
12
|
+
file = new(path, opts)
|
13
|
+
if block_given?
|
14
|
+
begin
|
15
|
+
yield file
|
16
|
+
ensure
|
17
|
+
file.close
|
18
|
+
end
|
19
|
+
else
|
20
|
+
file
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Create a File instance. Options are:
|
26
|
+
#
|
27
|
+
# :mode => :READ (default), :WRITE, or :RDWR
|
28
|
+
# :format => see list at File#format (default is :WAV)
|
29
|
+
# :encoding => see list at File#encoding (default is :PCM_16)
|
30
|
+
# :endian => see list at File#endian (default is :FILE)
|
31
|
+
# :samplerate => default is 44100
|
32
|
+
# :channles => default is 2
|
33
|
+
#
|
34
|
+
# When mode is :READ, then :format, :channels, and :samplerate are
|
35
|
+
# ignored -- unless the format is :RAW
|
36
|
+
#
|
37
|
+
# May raise Sndfile::Error on various error conditions
|
38
|
+
#
|
39
|
+
def initialize(path,opts={})
|
40
|
+
opts = opts.keyword_args(:mode => { :valid => Enums::FileMode.symbols, :default => :READ },
|
41
|
+
:format => { :valid => Enums::Format.symbols, :default => :WAV },
|
42
|
+
:encoding => { :valid => Enums::Encoding.symbols, :default => :PCM_16 },
|
43
|
+
:endian => { :valid => Enums::Endian.symbols, :default => :FILE },
|
44
|
+
:samplerate => 44100,
|
45
|
+
:channels => 2,
|
46
|
+
)
|
47
|
+
|
48
|
+
@path = path
|
49
|
+
@sfinfo = SfInfo.new
|
50
|
+
if opts.mode == :WRITE or opts.format == :RAW
|
51
|
+
@sfinfo[:format] = Enums::Format[opts.format]|Enums::Encoding[opts.encoding]|Enums::Endian[opts.endian]
|
52
|
+
@sfinfo[:channels] = opts.channels
|
53
|
+
@sfinfo[:samplerate] = opts.samplerate
|
54
|
+
end
|
55
|
+
@sfpointer = sf_open(path.to_s, opts.mode, @sfinfo)
|
56
|
+
check_error
|
57
|
+
sf_command @sfpointer, :SFC_SET_CLIPPING, nil, 1
|
58
|
+
check_error
|
59
|
+
end
|
60
|
+
|
61
|
+
# Closes the File instance.
|
62
|
+
#
|
63
|
+
# May raise Sndfile::Error for various error conditions
|
64
|
+
def close
|
65
|
+
check_error sf_close(@sfpointer)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the format of the file, which is one of
|
69
|
+
#
|
70
|
+
# :WAV - Microsoft WAV format (little endian).
|
71
|
+
# :AIFF - Apple/SGI AIFF format (big endian).
|
72
|
+
# :AU - Sun/NeXT AU format (big endian).
|
73
|
+
# :RAW - RAW PCM data.
|
74
|
+
# :PAF - Ensoniq PARIS file format.
|
75
|
+
# :SVX - Amiga IFF / SVX8 / SV16 format.
|
76
|
+
# :NIST - Sphere NIST format.
|
77
|
+
# :VOC - VOC files.
|
78
|
+
# :IRCAM - Berkeley/IRCAM/CARL
|
79
|
+
# :W64 - Sonic Foundry's 64 bit RIFF/WAV
|
80
|
+
# :MAT4 - Matlab (tm) V4.2 / GNU Octave 2.0
|
81
|
+
# :MAT5 - Matlab (tm) V5.0 / GNU Octave 2.1
|
82
|
+
# :PVF - Portable Voice Format
|
83
|
+
# :XI - Fasttracker 2 Extended Instrument
|
84
|
+
# :HTK - HMM Tool Kit format
|
85
|
+
# :SDS - Midi Sample Dump Standard
|
86
|
+
# :AVR - Audio Visual Research
|
87
|
+
# :WAVEX - MS WAVE with WAVEFORMATEX
|
88
|
+
# :SD2 - Sound Designer 2
|
89
|
+
# :FLAC - FLAC lossless file format
|
90
|
+
# :CAF - Core Audio File format
|
91
|
+
# :WVE - Psion WVE format
|
92
|
+
# :OGG - Xiph OGG container
|
93
|
+
# :MPC2K - Akai MPC 2000 sampler
|
94
|
+
# :RF64 - RF64 WAV file
|
95
|
+
def format
|
96
|
+
Format[@sfinfo[:format] & FORMAT_MASK]
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns the encoding of the file data, which is one of:
|
100
|
+
#
|
101
|
+
# :PCM_S8 - Signed 8 bit data
|
102
|
+
# :PCM_16 - Signed 16 bit data
|
103
|
+
# :PCM_24 - Signed 24 bit data
|
104
|
+
# :PCM_32 - Signed 32 bit data
|
105
|
+
# :PCM_U8 - Unsigned 8 bit data (WAV and RAW only)
|
106
|
+
# :FLOAT - 32 bit float data
|
107
|
+
# :DOUBLE - 64 bit float data
|
108
|
+
# :ULAW - U-Law encoded.
|
109
|
+
# :ALAW - A-Law encoded.
|
110
|
+
# :IMA_ADPCM - IMA ADPCM.
|
111
|
+
# :MS_ADPCM - Microsoft ADPCM.
|
112
|
+
# :GSM610 - GSM 6.10 encoding.
|
113
|
+
# :VOX_ADPCM - Oki Dialogic ADPCM encoding.
|
114
|
+
# :G721_32 - 32kbs G721 ADPCM encoding.
|
115
|
+
# :G723_24 - 24kbs G723 ADPCM encoding.
|
116
|
+
# :G723_40 - 40kbs G723 ADPCM encoding.
|
117
|
+
# :DWVW_12 - 12 bit Delta Width Variable Word encoding.
|
118
|
+
# :DWVW_16 - 16 bit Delta Width Variable Word encoding.
|
119
|
+
# :DWVW_24 - 24 bit Delta Width Variable Word encoding.
|
120
|
+
# :DWVW_N - N bit Delta Width Variable Word encoding.
|
121
|
+
# :DPCM_8 - 8 bit differential PCM (XI only)
|
122
|
+
# :DPCM_16 - 16 bit differential PCM (XI only)
|
123
|
+
# :VORBIS - Xiph Vorbis encoding.
|
124
|
+
def encoding
|
125
|
+
Encoding[@sfinfo[:format] & ENCODING_MASK]
|
126
|
+
end
|
127
|
+
|
128
|
+
# Returns the endian-ness of the data, one of:
|
129
|
+
#
|
130
|
+
# :FILE - Default file endian-ness.
|
131
|
+
# :LITTLE - Force little endian-ness.
|
132
|
+
# :BIG - Force big endian-ness.
|
133
|
+
# :CPU - Force CPU endian-ness.
|
134
|
+
def endian
|
135
|
+
Endian[@sfinfo[:format] & ENDIAN_MASK]
|
136
|
+
end
|
137
|
+
|
138
|
+
# Returns the number of frames (samples) in the file
|
139
|
+
def frames
|
140
|
+
@sfinfo[:frames]
|
141
|
+
end
|
142
|
+
|
143
|
+
# Returns the sample rate, frames per second
|
144
|
+
def samplerate
|
145
|
+
@sfinfo[:samplerate]
|
146
|
+
end
|
147
|
+
|
148
|
+
# Returns the number of channels of data
|
149
|
+
def channels
|
150
|
+
@sfinfo[:channels]
|
151
|
+
end
|
152
|
+
|
153
|
+
# Reads frames from the file, returning the data in a GSLng::Matrix of
|
154
|
+
# dimensions frames x channels. (For convenience, the height and width
|
155
|
+
# methods of GSLng::Matrix are aliased as GSLng::Matrix#frames and
|
156
|
+
# GSLng::Matrix#channels)
|
157
|
+
#
|
158
|
+
# Normally the requested number of frames is read, unless end of file is
|
159
|
+
# reached. If no frames are read (i.e. already at end of file),
|
160
|
+
# returns nil instead of a GSLng::Matrix.
|
161
|
+
#
|
162
|
+
# May raise Sndfile::Error in case of error.
|
163
|
+
def read(nframes)
|
164
|
+
|
165
|
+
buf = GSLng::Matrix.new(nframes, channels)
|
166
|
+
|
167
|
+
count = sf_readf_double @sfpointer, buf.data_ptr, nframes
|
168
|
+
check_error
|
169
|
+
case count
|
170
|
+
when 0 then nil
|
171
|
+
when nframes then buf
|
172
|
+
else buf.view(0, 0, count, channels)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Writes frames to the file. The data must be (quack like) a GSLng::Matrix
|
177
|
+
# with dimensions frames x channels. The matrix can contain any number of
|
178
|
+
# frames.
|
179
|
+
#
|
180
|
+
# When writing to a file with integer encoding, values are clipped to
|
181
|
+
# [-1, 1].
|
182
|
+
#
|
183
|
+
# May raise Sndfile::Error in case of error.
|
184
|
+
def write(buf)
|
185
|
+
sf_writef_double @sfpointer, buf.data_ptr, buf.frames
|
186
|
+
check_error
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
def check_error(code = nil)
|
192
|
+
code ||= sf_error(@sfpointer.null? ? nil : @sfpointer)
|
193
|
+
if code != 0
|
194
|
+
msg = sf_strerror(@sfpointer.null? ? nil : @sfpointer)
|
195
|
+
msg += " (#{ErrorCode[code]})" if ErrorCode[code]
|
196
|
+
msg += " [#{@path}]"
|
197
|
+
raise Sndfile::Error, msg
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Sndfile # :nodoc: all
|
2
|
+
module SndfileApi
|
3
|
+
extend FFI::Library
|
4
|
+
include Enums
|
5
|
+
|
6
|
+
ffi_lib 'libsndfile'
|
7
|
+
|
8
|
+
typedef :int64, :sf_count_t
|
9
|
+
|
10
|
+
class SfInfo < FFI::Struct
|
11
|
+
layout :frames, :sf_count_t,
|
12
|
+
:samplerate, :int,
|
13
|
+
:channels, :int,
|
14
|
+
:format, :int,
|
15
|
+
:sections, :int,
|
16
|
+
:seekable, :int
|
17
|
+
end
|
18
|
+
|
19
|
+
# SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) ;
|
20
|
+
# SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
|
21
|
+
# SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
|
22
|
+
# int sf_format_check (const SF_INFO *info) ;
|
23
|
+
attach_function :sf_open, [:string, FileMode, :pointer], :pointer
|
24
|
+
attach_function :sf_open_fd, [:int, :int, :pointer, :int], :pointer
|
25
|
+
attach_function :sf_open_virtual, [:pointer, :int, :pointer, :pointer], :pointer
|
26
|
+
attach_function :sf_format_check, [:pointer], :int
|
27
|
+
|
28
|
+
# sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) ;
|
29
|
+
attach_function :sf_seek, [:pointer, :sf_count_t, :int], :sf_count_t
|
30
|
+
|
31
|
+
# int sf_command (SNDFILE *sndfile, int cmd, void *data, int datasize) ;
|
32
|
+
attach_function :sf_command, [:pointer, Command, :pointer, :int], :int
|
33
|
+
|
34
|
+
# int sf_error (SNDFILE *sndfile) ;
|
35
|
+
# const char* sf_strerror (SNDFILE *sndfile) ;
|
36
|
+
# const char* sf_error_number (int errnum) ;
|
37
|
+
attach_function :sf_error, [:pointer], :int
|
38
|
+
attach_function :sf_strerror, [:pointer], :string
|
39
|
+
attach_function :sf_error_number, [:int], :string
|
40
|
+
|
41
|
+
# int sf_perror (SNDFILE *sndfile) ;
|
42
|
+
# int sf_error_str (SNDFILE *sndfile, char* str, size_t len) ;
|
43
|
+
attach_function :sf_perror, [:pointer], :int
|
44
|
+
attach_function :sf_error_str, [:pointer, :pointer, :int], :int
|
45
|
+
|
46
|
+
# int sf_close (SNDFILE *sndfile) ;
|
47
|
+
# void sf_write_sync (SNDFILE *sndfile) ;
|
48
|
+
attach_function :sf_close, [:pointer], :int
|
49
|
+
attach_function :sf_write_sync, [:pointer], :void
|
50
|
+
|
51
|
+
|
52
|
+
# sf_count_t sf_read_short (SNDFILE *sndfile, short *ptr, sf_count_t items) ;
|
53
|
+
# sf_count_t sf_read_int (SNDFILE *sndfile, int *ptr, sf_count_t items) ;
|
54
|
+
# sf_count_t sf_read_float (SNDFILE *sndfile, float *ptr, sf_count_t items) ;
|
55
|
+
# sf_count_t sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t items) ;
|
56
|
+
attach_function :sf_read_short, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
57
|
+
attach_function :sf_read_int, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
58
|
+
attach_function :sf_read_float, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
59
|
+
attach_function :sf_read_double, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
60
|
+
|
61
|
+
# sf_count_t sf_readf_short (SNDFILE *sndfile, short *ptr, sf_count_t frames) ;
|
62
|
+
# sf_count_t sf_readf_int (SNDFILE *sndfile, int *ptr, sf_count_t frames) ;
|
63
|
+
# sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames) ;
|
64
|
+
# sf_count_t sf_readf_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) ;
|
65
|
+
attach_function :sf_readf_short, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
66
|
+
attach_function :sf_readf_int, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
67
|
+
attach_function :sf_readf_float, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
68
|
+
attach_function :sf_readf_double, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
69
|
+
|
70
|
+
# sf_count_t sf_write_short (SNDFILE *sndfile, short *ptr, sf_count_t items) ;
|
71
|
+
# sf_count_t sf_write_int (SNDFILE *sndfile, int *ptr, sf_count_t items) ;
|
72
|
+
# sf_count_t sf_write_float (SNDFILE *sndfile, float *ptr, sf_count_t items) ;
|
73
|
+
# sf_count_t sf_write_double (SNDFILE *sndfile, double *ptr, sf_count_t items) ;
|
74
|
+
attach_function :sf_write_short, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
75
|
+
attach_function :sf_write_int, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
76
|
+
attach_function :sf_write_float, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
77
|
+
attach_function :sf_write_double, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
78
|
+
|
79
|
+
# sf_count_t sf_writef_short (SNDFILE *sndfile, short *ptr, sf_count_t frames) ;
|
80
|
+
# sf_count_t sf_writef_int (SNDFILE *sndfile, int *ptr, sf_count_t frames) ;
|
81
|
+
# sf_count_t sf_writef_float (SNDFILE *sndfile, float *ptr, sf_count_t frames) ;
|
82
|
+
# sf_count_t sf_writef_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) ;
|
83
|
+
attach_function :sf_writef_short, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
84
|
+
attach_function :sf_writef_int, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
85
|
+
attach_function :sf_writef_float, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
86
|
+
attach_function :sf_writef_double, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
87
|
+
|
88
|
+
# sf_count_t sf_read_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
|
89
|
+
# sf_count_t sf_write_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
|
90
|
+
attach_function :sf_read_raw, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
91
|
+
attach_function :sf_write_raw, [:pointer, :pointer, :sf_count_t], :sf_count_t
|
92
|
+
|
93
|
+
# const char* sf_get_string (SNDFILE *sndfile, int str_type) ;
|
94
|
+
# int sf_set_string (SNDFILE *sndfile, int str_type, const char* str) ;
|
95
|
+
attach_function :sf_get_string, [:pointer, :int], :string
|
96
|
+
attach_function :sf_set_string, [:pointer, :int, :string], :int
|
97
|
+
end
|
98
|
+
end
|
data/sndfile.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/sndfile/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["ronen barzel"]
|
6
|
+
gem.email = ["ronen@barzel.org"]
|
7
|
+
gem.description = %q{Ruby wrapper for libsndfile. Reads/writes data as GSL matrices, to allow fast processing.}
|
8
|
+
gem.summary = %q{Ruby wrapper for libsndfile. Reads/writes data as GSL matrices, to allow fast processing.}
|
9
|
+
gem.homepage = "https://github.com/ronen/sndfile"
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "sndfile"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Sndfile::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency("ffi")
|
19
|
+
gem.add_dependency("ruby-gsl-ng")
|
20
|
+
gem.add_dependency("hash_keyword_args")
|
21
|
+
|
22
|
+
gem.add_development_dependency 'rake'
|
23
|
+
gem.add_development_dependency 'rspec'
|
24
|
+
gem.add_development_dependency 'simplecov'
|
25
|
+
gem.add_development_dependency 'simplecov-gem-adapter'
|
26
|
+
end
|
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sndfile do
|
4
|
+
|
5
|
+
it "should return correct file info" do
|
6
|
+
Sndfile::File.open(INPUTS_DIR + "ComputerMagic.wav") do |f|
|
7
|
+
f.format.should == :WAV
|
8
|
+
f.encoding.should == :PCM_16
|
9
|
+
f.endian.should == :FILE
|
10
|
+
f.frames.should == 223451
|
11
|
+
f.samplerate.should == 44100
|
12
|
+
f.channels.should == 2
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should raise an error when it can't open the file" do
|
17
|
+
expect { Sndfile::File.open("/no/such/file") }.should raise_error Sndfile::Error
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'narray'
|
4
|
+
|
5
|
+
describe "Integration" do
|
6
|
+
|
7
|
+
it "should copy a file" do
|
8
|
+
inpath = in_path("ComputerMagic.wav")
|
9
|
+
outpath, refpath = out_ref_paths("copy.wav")
|
10
|
+
|
11
|
+
fin = Sndfile::File.open(inpath)
|
12
|
+
Sndfile::File.open(outpath, :mode => :WRITE, :format => :WAV, :encoding => :PCM_16, :channels => 2, :samplerate => fin.samplerate) do |fout|
|
13
|
+
while data = fin.read(12345)
|
14
|
+
fout.write(data)
|
15
|
+
end
|
16
|
+
system("cmp #{outpath} #{refpath}").should be_true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should mix two files to and write the result" do
|
21
|
+
inpath1 = in_path("ComputerMagic.wav")
|
22
|
+
inpath2 = in_path("Flute3.wav")
|
23
|
+
outpath, refpath = out_ref_paths("mix.wav")
|
24
|
+
|
25
|
+
fin1 = Sndfile::File.open(inpath1)
|
26
|
+
fin1.channels.should == 2
|
27
|
+
|
28
|
+
fin2 = Sndfile::File.open(inpath2)
|
29
|
+
fin2.channels.should == 1
|
30
|
+
fin1.samplerate.should == fin2.samplerate
|
31
|
+
|
32
|
+
Sndfile::File.open(outpath, :mode => :WRITE, :format => :WAV, :encoding => :PCM_16, :channels => 2, :samplerate => fin1.samplerate) do |fout|
|
33
|
+
while true
|
34
|
+
a = fin1.read(10000)
|
35
|
+
b = fin2.read(10000)
|
36
|
+
b = b * GSLng::Matrix.from_array([[1,0]]) if b
|
37
|
+
case
|
38
|
+
when a.nil? && b.nil?
|
39
|
+
break
|
40
|
+
when a.nil?
|
41
|
+
r = b
|
42
|
+
when b.nil?
|
43
|
+
r = a
|
44
|
+
when a.frames > b.frames
|
45
|
+
r = a
|
46
|
+
r.view(0, 0, b.frames, 2).add! b
|
47
|
+
when b.frames > a.frames
|
48
|
+
r = b
|
49
|
+
r.view(0, 0, a.frames, 2).add! a
|
50
|
+
else
|
51
|
+
r = a
|
52
|
+
r.add! b
|
53
|
+
end
|
54
|
+
fout.write(r)
|
55
|
+
end
|
56
|
+
system("cmp #{outpath} #{refpath}").should be_true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should multiply data by a scalar" do
|
61
|
+
inpath = in_path("ComputerMagic.wav")
|
62
|
+
outpath, refpath = out_ref_paths("half.wav")
|
63
|
+
|
64
|
+
fin = Sndfile::File.open(inpath)
|
65
|
+
Sndfile::File.open(outpath, :mode => :WRITE, :format => :WAV, :encoding => :PCM_16, :channels => 2, :samplerate => fin.samplerate) do |fout|
|
66
|
+
while data = fin.read(10000)
|
67
|
+
fout.write(data * 0.5)
|
68
|
+
end
|
69
|
+
system("cmp #{outpath} #{refpath}").should be_true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
if RUBY_VERSION > "1.9"
|
2
|
+
require 'simplecov'
|
3
|
+
require 'simplecov-gem-adapter'
|
4
|
+
SimpleCov.start 'gem'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rspec'
|
8
|
+
require 'sndfile'
|
9
|
+
|
10
|
+
# Requires supporting files with custom matchers and macros, etc,
|
11
|
+
# in ./support/ and its subdirectories.
|
12
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
INPUTS_DIR = Pathname.new(__FILE__) + "../inputs"
|
19
|
+
REFS_DIR = Pathname.new(__FILE__) + "../refs"
|
20
|
+
OUTPUTS_DIR = Pathname.new(__FILE__) + "../outputs"
|
21
|
+
Dir.mkdir(OUTPUTS_DIR) unless Dir.exist? OUTPUTS_DIR
|
22
|
+
|
23
|
+
def in_path(name)
|
24
|
+
INPUTS_DIR + name
|
25
|
+
end
|
26
|
+
|
27
|
+
def out_ref_paths(name)
|
28
|
+
[
|
29
|
+
OUTPUTS_DIR + "out-#{name}",
|
30
|
+
REFS_DIR + "ref-#{name}",
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sndfile
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- ronen barzel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ffi
|
16
|
+
requirement: &70255236835440 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70255236835440
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: ruby-gsl-ng
|
27
|
+
requirement: &70255236834820 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70255236834820
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: hash_keyword_args
|
38
|
+
requirement: &70255236850680 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70255236850680
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &70255236850240 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70255236850240
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rspec
|
60
|
+
requirement: &70255236849800 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70255236849800
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: &70255236849360 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70255236849360
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: simplecov-gem-adapter
|
82
|
+
requirement: &70255236848880 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70255236848880
|
91
|
+
description: Ruby wrapper for libsndfile. Reads/writes data as GSL matrices, to allow
|
92
|
+
fast processing.
|
93
|
+
email:
|
94
|
+
- ronen@barzel.org
|
95
|
+
executables: []
|
96
|
+
extensions: []
|
97
|
+
extra_rdoc_files: []
|
98
|
+
files:
|
99
|
+
- .gitignore
|
100
|
+
- Gemfile
|
101
|
+
- README.md
|
102
|
+
- Rakefile
|
103
|
+
- lib/gsl-ng/matrix.rb
|
104
|
+
- lib/sndfile.rb
|
105
|
+
- lib/sndfile/enums.rb
|
106
|
+
- lib/sndfile/error.rb
|
107
|
+
- lib/sndfile/file.rb
|
108
|
+
- lib/sndfile/sndfile_api.rb
|
109
|
+
- lib/sndfile/version.rb
|
110
|
+
- sndfile.gemspec
|
111
|
+
- spec/file_spec.rb
|
112
|
+
- spec/inputs/ComputerMagic.wav
|
113
|
+
- spec/inputs/Flute3.wav
|
114
|
+
- spec/integration_spec.rb
|
115
|
+
- spec/refs/ref-copy.wav
|
116
|
+
- spec/refs/ref-half.wav
|
117
|
+
- spec/refs/ref-mix.wav
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
homepage: https://github.com/ronen/sndfile
|
120
|
+
licenses: []
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ! '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 1.8.12
|
140
|
+
signing_key:
|
141
|
+
specification_version: 3
|
142
|
+
summary: Ruby wrapper for libsndfile. Reads/writes data as GSL matrices, to allow
|
143
|
+
fast processing.
|
144
|
+
test_files:
|
145
|
+
- spec/file_spec.rb
|
146
|
+
- spec/inputs/ComputerMagic.wav
|
147
|
+
- spec/inputs/Flute3.wav
|
148
|
+
- spec/integration_spec.rb
|
149
|
+
- spec/refs/ref-copy.wav
|
150
|
+
- spec/refs/ref-half.wav
|
151
|
+
- spec/refs/ref-mix.wav
|
152
|
+
- spec/spec_helper.rb
|
153
|
+
has_rdoc:
|