ruby-audio 1.5.0-x86-mingw32
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/LICENSE +340 -0
- data/README.rdoc +39 -0
- data/Rakefile +81 -0
- data/ext/rubyaudio_ext/extconf.rb +32 -0
- data/ext/rubyaudio_ext/ra_buffer.c +315 -0
- data/ext/rubyaudio_ext/ra_buffer.h +40 -0
- data/ext/rubyaudio_ext/ra_sound.c +506 -0
- data/ext/rubyaudio_ext/ra_sound.h +37 -0
- data/ext/rubyaudio_ext/ra_soundinfo.c +165 -0
- data/ext/rubyaudio_ext/ra_soundinfo.h +25 -0
- data/ext/rubyaudio_ext/rubyaudio_ext.c +92 -0
- data/lib/1.8/rubyaudio_ext.so +0 -0
- data/lib/1.9/rubyaudio_ext.so +0 -0
- data/lib/ruby-audio.rb +10 -0
- data/lib/ruby-audio/buffer.rb +25 -0
- data/lib/ruby-audio/sound.rb +85 -0
- data/lib/ruby-audio/sound_info.rb +66 -0
- data/ruby-audio.gemspec +22 -0
- data/spec/buffer_spec.rb +88 -0
- data/spec/data/what.mp3 +0 -0
- data/spec/data/what.wav +0 -0
- data/spec/data/what2.wav +0 -0
- data/spec/sound_info_spec.rb +49 -0
- data/spec/sound_spec.rb +182 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +11 -0
- metadata +101 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
#ifndef RA_SOUND_H
|
2
|
+
#define RA_SOUND_H
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <sndfile.h>
|
6
|
+
#include "ra_soundinfo.h"
|
7
|
+
#include "ra_buffer.h"
|
8
|
+
|
9
|
+
typedef struct {
|
10
|
+
SNDFILE *snd;
|
11
|
+
VALUE info;
|
12
|
+
int mode;
|
13
|
+
int closed;
|
14
|
+
} RA_SOUND;
|
15
|
+
|
16
|
+
void Init_ra_sound();
|
17
|
+
|
18
|
+
/*** Initialization and Memory Manangement ***/
|
19
|
+
static VALUE ra_sound_allocate(VALUE klass);
|
20
|
+
static void ra_sound_mark(RA_SOUND *snd);
|
21
|
+
static void ra_sound_free(RA_SOUND *snd);
|
22
|
+
|
23
|
+
/*** Singleton Methods ***/
|
24
|
+
static VALUE ra_sound_s_open(int argc, VALUE *argv, VALUE klass);
|
25
|
+
|
26
|
+
/*** Instance Methods ***/
|
27
|
+
static VALUE ra_sound_init(VALUE self, VALUE path, VALUE mode, VALUE info);
|
28
|
+
static VALUE ra_sound_info(VALUE self);
|
29
|
+
static VALUE ra_sound_seek(VALUE self, VALUE frames, VALUE whence);
|
30
|
+
static VALUE ra_sound_read(VALUE self, VALUE buf, VALUE frames);
|
31
|
+
static VALUE ra_sound_write(VALUE self, VALUE buf);
|
32
|
+
static VALUE ra_sound_addbuf(VALUE self, VALUE buf);
|
33
|
+
static VALUE ra_sound_close(VALUE self);
|
34
|
+
static VALUE ra_sound_close_safe(VALUE self);
|
35
|
+
static VALUE ra_sound_closed(VALUE self);
|
36
|
+
|
37
|
+
#endif // #ifndef RA_SOUND_H
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#include "ra_soundinfo.h"
|
2
|
+
|
3
|
+
extern VALUE eRubyAudioError;
|
4
|
+
|
5
|
+
/*
|
6
|
+
* Class <code>CSoundInfo</code> is a very light wrapper around the
|
7
|
+
* <code>SF_INFO</code> struct exposed by libsndfile. It provides information
|
8
|
+
* about open sound files like format, length, samplerate, channels, and other
|
9
|
+
* things. In addition it can be used to specify the format of new sound files.
|
10
|
+
*/
|
11
|
+
void Init_ra_soundinfo() {
|
12
|
+
VALUE mRubyAudio = rb_define_module("RubyAudio");
|
13
|
+
VALUE cRASoundInfo = rb_define_class_under(mRubyAudio, "CSoundInfo", rb_cObject);
|
14
|
+
rb_define_alloc_func(cRASoundInfo, ra_soundinfo_allocate);
|
15
|
+
rb_define_method(cRASoundInfo, "valid?", ra_soundinfo_valid, 0);
|
16
|
+
rb_define_method(cRASoundInfo, "frames", ra_soundinfo_frames, 0);
|
17
|
+
rb_define_method(cRASoundInfo, "samplerate", ra_soundinfo_samplerate, 0);
|
18
|
+
rb_define_method(cRASoundInfo, "samplerate=", ra_soundinfo_samplerate_set, 1);
|
19
|
+
rb_define_method(cRASoundInfo, "channels", ra_soundinfo_channels, 0);
|
20
|
+
rb_define_method(cRASoundInfo, "channels=", ra_soundinfo_channels_set, 1);
|
21
|
+
rb_define_method(cRASoundInfo, "format", ra_soundinfo_format, 0);
|
22
|
+
rb_define_method(cRASoundInfo, "format=", ra_soundinfo_format_set, 1);
|
23
|
+
rb_define_method(cRASoundInfo, "sections", ra_soundinfo_sections, 0);
|
24
|
+
rb_define_method(cRASoundInfo, "seekable", ra_soundinfo_seekable, 0);
|
25
|
+
}
|
26
|
+
|
27
|
+
static VALUE ra_soundinfo_allocate(VALUE klass) {
|
28
|
+
SF_INFO *info = ALLOC(SF_INFO);
|
29
|
+
memset(info, 0, sizeof(SF_INFO));
|
30
|
+
VALUE self = Data_Wrap_Struct(klass, NULL, ra_soundinfo_free, info);
|
31
|
+
return self;
|
32
|
+
}
|
33
|
+
|
34
|
+
static void ra_soundinfo_free(SF_INFO *info) {
|
35
|
+
xfree(info);
|
36
|
+
}
|
37
|
+
|
38
|
+
/*
|
39
|
+
* call-seq:
|
40
|
+
* info.valid? => true or false
|
41
|
+
*
|
42
|
+
* Calls <code>sf_format_check</code> on the underlying <code>SF_INFO</code>
|
43
|
+
* struct and returns true or false based on validity. Used when creating a new
|
44
|
+
* sound file to check that the format has enough information to properly create
|
45
|
+
* a new sound.
|
46
|
+
*/
|
47
|
+
static VALUE ra_soundinfo_valid(VALUE self) {
|
48
|
+
SF_INFO *info;
|
49
|
+
Data_Get_Struct(self, SF_INFO, info);
|
50
|
+
return sf_format_check(info) ? Qtrue : Qfalse;
|
51
|
+
}
|
52
|
+
|
53
|
+
/*
|
54
|
+
* call-seq:
|
55
|
+
* info.frames => integer
|
56
|
+
*
|
57
|
+
* Returns the number of frames in the associated sound file.
|
58
|
+
*/
|
59
|
+
static VALUE ra_soundinfo_frames(VALUE self) {
|
60
|
+
SF_INFO *info;
|
61
|
+
Data_Get_Struct(self, SF_INFO, info);
|
62
|
+
return OFFT2NUM(info->frames);
|
63
|
+
}
|
64
|
+
|
65
|
+
/*
|
66
|
+
* call-seq:
|
67
|
+
* info.samplerate => integer
|
68
|
+
*
|
69
|
+
* Returns the samplerate of the associated sound file.
|
70
|
+
*/
|
71
|
+
static VALUE ra_soundinfo_samplerate(VALUE self) {
|
72
|
+
SF_INFO *info;
|
73
|
+
Data_Get_Struct(self, SF_INFO, info);
|
74
|
+
return INT2FIX(info->samplerate);
|
75
|
+
}
|
76
|
+
|
77
|
+
/*
|
78
|
+
* call-seq:
|
79
|
+
* info.samplerate = integer => integer
|
80
|
+
*
|
81
|
+
* Set the samplerate for a new sound created with the given info object.
|
82
|
+
*/
|
83
|
+
static VALUE ra_soundinfo_samplerate_set(VALUE self, VALUE new_samplerate) {
|
84
|
+
SF_INFO *info;
|
85
|
+
Data_Get_Struct(self, SF_INFO, info);
|
86
|
+
info->samplerate = FIX2INT(new_samplerate);
|
87
|
+
return new_samplerate;
|
88
|
+
}
|
89
|
+
|
90
|
+
/*
|
91
|
+
* call-seq:
|
92
|
+
* info.channels => integer
|
93
|
+
*
|
94
|
+
* Returns the number of channels in the associated sound file.
|
95
|
+
*/
|
96
|
+
static VALUE ra_soundinfo_channels(VALUE self) {
|
97
|
+
SF_INFO *info;
|
98
|
+
Data_Get_Struct(self, SF_INFO, info);
|
99
|
+
return INT2FIX(info->channels);
|
100
|
+
}
|
101
|
+
|
102
|
+
/*
|
103
|
+
* call-seq:
|
104
|
+
* info.channels = integer => integer
|
105
|
+
*
|
106
|
+
* Set the number of channels for a new sound created with the given info object.
|
107
|
+
*/
|
108
|
+
static VALUE ra_soundinfo_channels_set(VALUE self, VALUE new_channels) {
|
109
|
+
SF_INFO *info;
|
110
|
+
Data_Get_Struct(self, SF_INFO, info);
|
111
|
+
info->channels = FIX2INT(new_channels);
|
112
|
+
return new_channels;
|
113
|
+
}
|
114
|
+
|
115
|
+
/*
|
116
|
+
* call-seq:
|
117
|
+
* info.format => integer
|
118
|
+
*
|
119
|
+
* Returns the format as a combination of binary flags of the associated sound file.
|
120
|
+
*/
|
121
|
+
static VALUE ra_soundinfo_format(VALUE self) {
|
122
|
+
SF_INFO *info;
|
123
|
+
Data_Get_Struct(self, SF_INFO, info);
|
124
|
+
return INT2FIX(info->format);
|
125
|
+
}
|
126
|
+
|
127
|
+
/*
|
128
|
+
* call-seq:
|
129
|
+
* info.format = integer => integer
|
130
|
+
*
|
131
|
+
* Set the format for a new sound created with the given info object.
|
132
|
+
*
|
133
|
+
* info = RubyAudio::CSoundInfo.new
|
134
|
+
* info.format = RubyAudio::FORMAT_WAV|RubyAudio::FORMAT_PCM_16
|
135
|
+
*/
|
136
|
+
static VALUE ra_soundinfo_format_set(VALUE self, VALUE new_format) {
|
137
|
+
SF_INFO *info;
|
138
|
+
Data_Get_Struct(self, SF_INFO, info);
|
139
|
+
info->format = FIX2INT(new_format);
|
140
|
+
return new_format;
|
141
|
+
}
|
142
|
+
|
143
|
+
/*
|
144
|
+
* call-seq:
|
145
|
+
* info.sections => integer
|
146
|
+
*
|
147
|
+
* Returns the number of sections in the associated sound file.
|
148
|
+
*/
|
149
|
+
static VALUE ra_soundinfo_sections(VALUE self) {
|
150
|
+
SF_INFO *info;
|
151
|
+
Data_Get_Struct(self, SF_INFO, info);
|
152
|
+
return INT2FIX(info->sections);
|
153
|
+
}
|
154
|
+
|
155
|
+
/*
|
156
|
+
* call-seq:
|
157
|
+
* info.seekable => true or false
|
158
|
+
*
|
159
|
+
* Whether seeking is supported for the associated sound file.
|
160
|
+
*/
|
161
|
+
static VALUE ra_soundinfo_seekable(VALUE self) {
|
162
|
+
SF_INFO *info;
|
163
|
+
Data_Get_Struct(self, SF_INFO, info);
|
164
|
+
return info->seekable ? Qtrue : Qfalse;
|
165
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#ifndef RA_SOUNDINFO_H
|
2
|
+
#define RA_SOUNDINFO_H
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <sndfile.h>
|
6
|
+
|
7
|
+
void Init_ra_soundinfo();
|
8
|
+
|
9
|
+
/*** Initialization and Memory Manangement ***/
|
10
|
+
static VALUE ra_soundinfo_allocate(VALUE klass);
|
11
|
+
static void ra_soundinfo_free(SF_INFO *info);
|
12
|
+
|
13
|
+
/*** Instance Methods ***/
|
14
|
+
static VALUE ra_soundinfo_valid(VALUE self);
|
15
|
+
static VALUE ra_soundinfo_frames(VALUE self);
|
16
|
+
static VALUE ra_soundinfo_samplerate(VALUE self);
|
17
|
+
static VALUE ra_soundinfo_samplerate_set(VALUE self, VALUE new_samplerate);
|
18
|
+
static VALUE ra_soundinfo_channels(VALUE self);
|
19
|
+
static VALUE ra_soundinfo_channels_set(VALUE self, VALUE new_channels);
|
20
|
+
static VALUE ra_soundinfo_format(VALUE self);
|
21
|
+
static VALUE ra_soundinfo_format_set(VALUE self, VALUE new_format);
|
22
|
+
static VALUE ra_soundinfo_sections(VALUE self);
|
23
|
+
static VALUE ra_soundinfo_seekable(VALUE self);
|
24
|
+
|
25
|
+
#endif // #ifndef RA_SOUNDINFO_H
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <sndfile.h>
|
3
|
+
|
4
|
+
void Init_ra_buffer();
|
5
|
+
void Init_ra_soundinfo();
|
6
|
+
void Init_ra_sound();
|
7
|
+
|
8
|
+
VALUE eRubyAudioError;
|
9
|
+
|
10
|
+
/*
|
11
|
+
* Document-module: RubyAudio
|
12
|
+
*/
|
13
|
+
/*
|
14
|
+
* Document-class: RubyAudio::Error
|
15
|
+
*
|
16
|
+
* Error class for RubyAudio
|
17
|
+
*/
|
18
|
+
void Init_rubyaudio_ext() {
|
19
|
+
// Create RubyAudio module and other setup
|
20
|
+
VALUE mRubyAudio = rb_define_module("RubyAudio");
|
21
|
+
eRubyAudioError = rb_define_class_under(mRubyAudio, "Error", rb_eStandardError);
|
22
|
+
|
23
|
+
// Set up classes
|
24
|
+
Init_ra_buffer();
|
25
|
+
Init_ra_soundinfo();
|
26
|
+
Init_ra_sound();
|
27
|
+
|
28
|
+
// Export libsndfile constants
|
29
|
+
// Major formats
|
30
|
+
rb_define_const(mRubyAudio, "FORMAT_WAV", /* 0x010000 */ INT2FIX(SF_FORMAT_WAV));
|
31
|
+
rb_define_const(mRubyAudio, "FORMAT_AIFF", /* 0x020000 */ INT2FIX(SF_FORMAT_AIFF));
|
32
|
+
rb_define_const(mRubyAudio, "FORMAT_AU", /* 0x030000 */ INT2FIX(SF_FORMAT_AU));
|
33
|
+
rb_define_const(mRubyAudio, "FORMAT_RAW", /* 0x040000 */ INT2FIX(SF_FORMAT_RAW));
|
34
|
+
rb_define_const(mRubyAudio, "FORMAT_PAF", /* 0x050000 */ INT2FIX(SF_FORMAT_PAF));
|
35
|
+
rb_define_const(mRubyAudio, "FORMAT_SVX", /* 0x060000 */ INT2FIX(SF_FORMAT_SVX));
|
36
|
+
rb_define_const(mRubyAudio, "FORMAT_NIST", /* 0x070000 */ INT2FIX(SF_FORMAT_NIST));
|
37
|
+
rb_define_const(mRubyAudio, "FORMAT_VOC", /* 0x080000 */ INT2FIX(SF_FORMAT_VOC));
|
38
|
+
rb_define_const(mRubyAudio, "FORMAT_IRCAM", /* 0x0A0000 */ INT2FIX(SF_FORMAT_IRCAM));
|
39
|
+
rb_define_const(mRubyAudio, "FORMAT_W64", /* 0x0B0000 */ INT2FIX(SF_FORMAT_W64));
|
40
|
+
rb_define_const(mRubyAudio, "FORMAT_MAT4", /* 0x0C0000 */ INT2FIX(SF_FORMAT_MAT4));
|
41
|
+
rb_define_const(mRubyAudio, "FORMAT_MAT5", /* 0x0D0000 */ INT2FIX(SF_FORMAT_MAT5));
|
42
|
+
rb_define_const(mRubyAudio, "FORMAT_PVF", /* 0x0E0000 */ INT2FIX(SF_FORMAT_PVF));
|
43
|
+
rb_define_const(mRubyAudio, "FORMAT_XI", /* 0x0F0000 */ INT2FIX(SF_FORMAT_XI));
|
44
|
+
rb_define_const(mRubyAudio, "FORMAT_HTK", /* 0x100000 */ INT2FIX(SF_FORMAT_HTK));
|
45
|
+
rb_define_const(mRubyAudio, "FORMAT_SDS", /* 0x110000 */ INT2FIX(SF_FORMAT_SDS));
|
46
|
+
rb_define_const(mRubyAudio, "FORMAT_AVR", /* 0x120000 */ INT2FIX(SF_FORMAT_AVR));
|
47
|
+
rb_define_const(mRubyAudio, "FORMAT_WAVEX", /* 0x130000 */ INT2FIX(SF_FORMAT_WAVEX));
|
48
|
+
rb_define_const(mRubyAudio, "FORMAT_SD2", /* 0x160000 */ INT2FIX(SF_FORMAT_SD2));
|
49
|
+
rb_define_const(mRubyAudio, "FORMAT_FLAC", /* 0x170000 */ INT2FIX(SF_FORMAT_FLAC));
|
50
|
+
rb_define_const(mRubyAudio, "FORMAT_CAF", /* 0x180000 */ INT2FIX(SF_FORMAT_CAF));
|
51
|
+
#ifdef HAVE_CONST_SF_FORMAT_OGG
|
52
|
+
rb_define_const(mRubyAudio, "FORMAT_OGG", /* 0x200000 */ INT2FIX(SF_FORMAT_OGG));
|
53
|
+
#endif
|
54
|
+
|
55
|
+
// Subtypes from here on
|
56
|
+
rb_define_const(mRubyAudio, "FORMAT_PCM_S8", /* 0x0001 */ INT2FIX(SF_FORMAT_PCM_S8));
|
57
|
+
rb_define_const(mRubyAudio, "FORMAT_PCM_16", /* 0x0002 */ INT2FIX(SF_FORMAT_PCM_16));
|
58
|
+
rb_define_const(mRubyAudio, "FORMAT_PCM_24", /* 0x0003 */ INT2FIX(SF_FORMAT_PCM_24));
|
59
|
+
rb_define_const(mRubyAudio, "FORMAT_PCM_32", /* 0x0004 */ INT2FIX(SF_FORMAT_PCM_32));
|
60
|
+
rb_define_const(mRubyAudio, "FORMAT_PCM_U8", /* 0x0005 */ INT2FIX(SF_FORMAT_PCM_U8));
|
61
|
+
rb_define_const(mRubyAudio, "FORMAT_FLOAT", /* 0x0006 */ INT2FIX(SF_FORMAT_FLOAT));
|
62
|
+
rb_define_const(mRubyAudio, "FORMAT_DOUBLE", /* 0x0007 */ INT2FIX(SF_FORMAT_DOUBLE));
|
63
|
+
rb_define_const(mRubyAudio, "FORMAT_ULAW", /* 0x0010 */ INT2FIX(SF_FORMAT_ULAW));
|
64
|
+
rb_define_const(mRubyAudio, "FORMAT_ALAW", /* 0x0011 */ INT2FIX(SF_FORMAT_ALAW));
|
65
|
+
rb_define_const(mRubyAudio, "FORMAT_IMA_ADPCM", /* 0x0012 */ INT2FIX(SF_FORMAT_IMA_ADPCM));
|
66
|
+
rb_define_const(mRubyAudio, "FORMAT_MS_ADPCM", /* 0x0013 */ INT2FIX(SF_FORMAT_MS_ADPCM));
|
67
|
+
rb_define_const(mRubyAudio, "FORMAT_GSM610", /* 0x0020 */ INT2FIX(SF_FORMAT_GSM610));
|
68
|
+
rb_define_const(mRubyAudio, "FORMAT_VOX_ADPCM", /* 0x0021 */ INT2FIX(SF_FORMAT_VOX_ADPCM));
|
69
|
+
rb_define_const(mRubyAudio, "FORMAT_G721_32", /* 0x0030 */ INT2FIX(SF_FORMAT_G721_32));
|
70
|
+
rb_define_const(mRubyAudio, "FORMAT_G723_24", /* 0x0031 */ INT2FIX(SF_FORMAT_G723_24));
|
71
|
+
rb_define_const(mRubyAudio, "FORMAT_G723_40", /* 0x0032 */ INT2FIX(SF_FORMAT_G723_40));
|
72
|
+
rb_define_const(mRubyAudio, "FORMAT_DWVW_12", /* 0x0040 */ INT2FIX(SF_FORMAT_DWVW_12));
|
73
|
+
rb_define_const(mRubyAudio, "FORMAT_DWVW_16", /* 0x0041 */ INT2FIX(SF_FORMAT_DWVW_16));
|
74
|
+
rb_define_const(mRubyAudio, "FORMAT_DWVW_24", /* 0x0042 */ INT2FIX(SF_FORMAT_DWVW_24));
|
75
|
+
rb_define_const(mRubyAudio, "FORMAT_DWVW_N", /* 0x0043 */ INT2FIX(SF_FORMAT_DWVW_N));
|
76
|
+
rb_define_const(mRubyAudio, "FORMAT_DPCM_8", /* 0x0050 */ INT2FIX(SF_FORMAT_DPCM_8));
|
77
|
+
rb_define_const(mRubyAudio, "FORMAT_DPCM_16", /* 0x0051 */ INT2FIX(SF_FORMAT_DPCM_16));
|
78
|
+
#ifdef HAVE_CONST_SF_FORMAT_OGG
|
79
|
+
rb_define_const(mRubyAudio, "FORMAT_VORBIS", /* 0x0060 */ INT2FIX(SF_FORMAT_VORBIS));
|
80
|
+
#endif
|
81
|
+
|
82
|
+
// Endian-ness options
|
83
|
+
rb_define_const(mRubyAudio, "ENDIAN_FILE", /* 0x00000000 */ INT2FIX(SF_ENDIAN_FILE));
|
84
|
+
rb_define_const(mRubyAudio, "ENDIAN_LITTLE", /* 0x10000000 */ INT2FIX(SF_ENDIAN_LITTLE));
|
85
|
+
rb_define_const(mRubyAudio, "ENDIAN_BIG", /* 0x20000000 */ INT2FIX(SF_ENDIAN_BIG));
|
86
|
+
rb_define_const(mRubyAudio, "ENDIAN_CPU", /* 0x30000000 */ INT2FIX(SF_ENDIAN_CPU));
|
87
|
+
|
88
|
+
// Format masks
|
89
|
+
rb_define_const(mRubyAudio, "FORMAT_SUBMASK", /* 0x0000FFFF */ INT2FIX(SF_FORMAT_SUBMASK));
|
90
|
+
rb_define_const(mRubyAudio, "FORMAT_TYPEMASK", /* 0x0FFF0000 */ INT2FIX(SF_FORMAT_TYPEMASK));
|
91
|
+
rb_define_const(mRubyAudio, "FORMAT_ENDMASK", /* 0x30000000 */ INT2FIX(SF_FORMAT_ENDMASK));
|
92
|
+
}
|
Binary file
|
Binary file
|
data/lib/ruby-audio.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module RubyAudio
|
2
|
+
# The <code>Buffer</code> class contains sound data read out of the sound. It
|
3
|
+
# can store a fixed maximum number of multi-channel audio frames of a specifi
|
4
|
+
# data type. Valid types are <code>short</code>, <code>int</code>,
|
5
|
+
# <code>float</code>, and <code>double</code>. The channel count must match up
|
6
|
+
# to the channel count of the sounds being read and written to. Trying to read
|
7
|
+
# into a buffer with the wrong number of channels will result in an error.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# buf = RubyAudio::Buffer.float(1000)
|
11
|
+
# buf = RubyAudio::Buffer.new("float", 1000, 1)
|
12
|
+
class Buffer < CBuffer
|
13
|
+
include Enumerable
|
14
|
+
|
15
|
+
def each
|
16
|
+
self.size.times do |i|
|
17
|
+
yield self[i]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
[:short, :int, :float, :double].each do |type|
|
22
|
+
eval "def self.#{type}(frames, channels=1); self.new(:#{type}, frames, channels); end"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module RubyAudio
|
2
|
+
# Class <code>Sound</code> wraps libsndfile to provide simple reading and
|
3
|
+
# writing for a wide variety of file formats
|
4
|
+
#
|
5
|
+
# Reading Example:
|
6
|
+
# RubyAudio::Sound.open('sound.wav') do |snd|
|
7
|
+
# buf = snd.read(:float, 100)
|
8
|
+
# puts buf.real_size #=> 100
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# Writing Example:
|
12
|
+
# buf = RubyAudio::Buffer.float(1000)
|
13
|
+
# out = nil
|
14
|
+
# ['snd1.wav', 'snd2.wav', 'snd3.wav'].each do |file|
|
15
|
+
# RubyAudio::Sound.open(file) do |snd|
|
16
|
+
# out = RubyAudio::Sound.open('out.wav', 'w', snd.info.clone) if out.nil?
|
17
|
+
#
|
18
|
+
# while snd.read(buf) != 0
|
19
|
+
# out.write(buf)
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# out.close if out
|
24
|
+
class Sound < CSound
|
25
|
+
# Creates a new <code>Sound</code> object for the audio file at the given path.
|
26
|
+
# Mode defaults to <code>"r"</code>, but valid modes are <code>"r"</code>,
|
27
|
+
# <code>"w"</code>, and <code>"rw"</code>.
|
28
|
+
#
|
29
|
+
# When creating a new sound, a valid <code>SoundInfo</code> object must be
|
30
|
+
# passed in, as libsndfile uses it to determine the output format.
|
31
|
+
# info = RubyAudio::SoundInfo.new :channels => 1, :samplerate => 48000, :format => RubyAudio::FORMAT_WAV|RubyAudio::FORMAT_PCM_16
|
32
|
+
# snd = RubyAudio::Sound.new "new.wav", 'r', info
|
33
|
+
def initialize(path, mode='r', info=nil)
|
34
|
+
info ||= SoundInfo.new
|
35
|
+
super(path, mode, info)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Seeks to a given offset <i>anInteger</i> in the sound according to the value
|
39
|
+
# of <i>whence</i>:
|
40
|
+
#
|
41
|
+
# IO::SEEK_CUR | Seeks to _frames_ plus current position
|
42
|
+
# --------------+----------------------------------------------------
|
43
|
+
# IO::SEEK_END | Seeks to _frames_ plus end of stream (you probably
|
44
|
+
# | want a negative value for _frames_)
|
45
|
+
# --------------+----------------------------------------------------
|
46
|
+
# IO::SEEK_SET | Seeks to the absolute location given by _frames_
|
47
|
+
def seek(frames, whence=IO::SEEK_SET)
|
48
|
+
super(frames, whence)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Reads a given number of frames from the sound into a buffer
|
52
|
+
#
|
53
|
+
# When given a buffer as the first argument, it reads data into that buffer
|
54
|
+
# reading an optional number of frames as the second argument. It returns
|
55
|
+
# the number of frames read.
|
56
|
+
#
|
57
|
+
# Example:
|
58
|
+
# buf = RubyAudio::Buffer.float(1000)
|
59
|
+
# snd.read(buf) #=> 1000
|
60
|
+
# snd.read(buf, 50) #=> 50
|
61
|
+
#
|
62
|
+
# When given a string or symbol as the first argument, it interprets this as
|
63
|
+
# the data type and creates a new buffer of the given size to read the data
|
64
|
+
# into. The buffer is correctly initialized with the proper number of channels
|
65
|
+
# to hold data from that sound.
|
66
|
+
#
|
67
|
+
# Example:
|
68
|
+
# buf = snd.read("int", 1000)
|
69
|
+
def read(*args)
|
70
|
+
case args[0]
|
71
|
+
when Buffer
|
72
|
+
buf = args[0]
|
73
|
+
size = args[1] || buf.size
|
74
|
+
return super(buf, size)
|
75
|
+
when Symbol, String
|
76
|
+
type = args[0]
|
77
|
+
buf = Buffer.new(type, args[1], info.channels)
|
78
|
+
super(buf, buf.size)
|
79
|
+
return buf
|
80
|
+
else
|
81
|
+
raise ArgumentError, "invalid arguments"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|