From: Charles Turner Date: 2008-08-21T13:11:38+09:00 Subject: 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: 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