Ruby/DL: How to create and use a buffer?

Hi all-

I’m trying to hookup Erik de Castro Lopo’s libsndfile with Ruby via
Ruby/DL: my first encounter with it. I’ve had some success with DL, but
am stuck at creating a multibyte buffer that can be passed by reference
into the libsndfile library.

libsndfile: http://www.mega-nerd.com/libsndfile/

me: Darwin spinoza.local 9.4.0 Darwin Kernel Version 9.4.0: Mon Jun 9
19:30:53 PDT 2008; root:xnu-1228.5.20~1/RELEASE_I386 i386

Ruby 1.9: ruby 1.9.0 (2007-12-25 revision 14709) [i686-darwin9.4.0]

My code is included below.

As you can see, I can malloc a DL::CPtr (buffer) and pass it into the
sf_readf_short() function. But I’m unclear what to do with it
afterwards.

I’ve been able to reference data by treating buffer like an array, like
so: buffer[2], but I’m not sure I’m getting valid data. It doesn’t look
right, but I haven’t compared it the audio file I’m using.

Any thoughts greatly appreciated!

Best, Charles Turner

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . .

require ‘dl’
require ‘dl/import’

module SndFile
extend ::DL::Importer

dlload “libsndfile.dylib”

SF_INFO = struct [
“long long frames”,
“int samplerate”,
“int channels”,
“int format”,
“int sections”,
“int seekable”,
]

Modes for opening files.

SFM_READ = 0x10
SFM_WRITE = 0x20
SFM_RDWR = 0x30

Major formats.

SF_FORMAT_WAV = 0x010000 # Microsoft WAV format
SF_FORMAT_AIFF = 0x020000 # Apple/SGI AIFF format

Minor formats

SF_FORMAT_PCM_S8 = 0x0001 # Signed 8 bit data
SF_FORMAT_PCM_16 = 0x0002 # Signed 16 bit data
SF_FORMAT_PCM_24 = 0x0003 # Signed 24 bit data
SF_FORMAT_PCM_32 = 0x0004 # Signed 32 bit data

SF_FORMAT_PCM_U8 = 0x0005 # Unsigned 8 bit data

SF_FORMAT_FLOAT = 0x0006 # 32 bit float data
SF_FORMAT_DOUBLE = 0x0007 # 64 bit float data

extern “int sf_format_check(SF_INFO*)”
extern “SNDFILE* sf_open(char*, int, SF_INFO*)”
extern “long long sf_readf_short(SNDFILE*, short*, long long)”
extern “int sf_close(SNDFILE*)”

end

sfinfo = SndFile::SF_INFO.malloc()

sndfile = SndFile.sf_open(“foo32.wav”, SndFile::SFM_READ, sfinfo)

sfinfo.frames # => 53248
sfinfo.samplerate # => 44100
sfinfo.channels # => 1
sfinfo.format.to_s(16) # => “10004”
sfinfo.sections # => 1
sfinfo.seekable # => 1

buffer = DL::CPtr.malloc(40)

frames = SndFile.sf_readf_short( sndfile, buffer, 10 )
frames # => 10

result = SndFile.sf_close( sndfile )
result # => 0

On Thu, 21 Aug 2008 13:11:38 +0900, Charles Turner wrote:

I’m trying to hookup Erik de Castro Lopo’s libsndfile with Ruby via
Ruby/DL:

OK, responding to my own question because I think I’ve got it:

buffer = DL::CPtr.malloc(40)

frames = SndFile.sf_readf_int( sndfile, buffer, 10 )
frames # => 10

buffer[0,40] # =>
“qs\xDB\x8F`\x906\x8C\xF1\x16\x06\x89\x1C:M\x86X\xB5\x0E\x84\x9E\xC9L\x82\xE8:\t\x81\xB4OE\x80\x7F\xCA\x01\x80\xC7\xF1>\x80”

Seems to work fine. It appears that Ruby/DL isn’t too happy with
libsndfile’s sf_readf_short() function, and in that case, my buffer
seems to contain only the two MSBs of each 32-bit address. But I may
still be doing something wrong.

Changing my audio file format to 32-bit integer data from 16-bit shows
everything to be OK.

Best, Charles

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs