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


C

Charles Turner

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
 
Ad

Advertisements

C

Charles Turner

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top