r8b.dll include file

Share your advanced PureBasic knowledge/code with the community.
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

r8b.dll include file

Post by Dreamland Fantasy »

Here is an include file for the r8b.dll used for resampling uncompressed WAV files. A big thank you to eriansa for suggesting this library.

The include file (r8b.pbi):

Code: Select all

;/  ***************************************************************************
;/  ****                                                                   ****
;/  ****    PureBasic include file for Aleksey Vaneev's r8b.dll library    ****
;/  ****  (r8b.dll available from http://www.voxengo.com/product/r8brain)  ****
;/  ****                                                                   ****
;/  ****          Programmed by Francis G. Loch, 8th January 2008          ****
;/  ****                  e-mail: francis@dfstudios.co.uk                  ****
;/  ****                                                                   ****
;/  ***************************************************************************

;- Constants

Enumeration               ; r8b quality constants
  #TR8B_QUALITY_VERYLOW
  #TR8B_QUALITY_LOW       ; Please note that these constants are not part of
  #TR8B_QUALITY_MEDIUM    ; the r8b.dll API, but have been added to aid code
  #TR8B_QUALITY_HIGH      ; readability
  #TR8B_QUALITY_VERYHIGH
EndEnumeration

;- Structures

Structure TR8BInputFormat
  Buffer.l
  Rate.l
  BitDepth.l
  Channels.l
  IEEE.l
  Len.l
EndStructure

Structure TR8BError
  WasError.b
  ErrMsg.c[128]
EndStructure

;- Procedures

Global r8bLib.l
Procedure.l Init_r8b()
  r8bLib = OpenLibrary(#PB_Any, "r8b.dll")
  ProcedureReturn IsLibrary(r8bLib)
EndProcedure

Procedure.l r8b_getWAVInfo(*fname.s, *SR.l, *Depth.l, *err.TR8BError)
  ProcedureReturn CallCFunction(r8bLib, "r8b_getWAVInfo", *fname, *SR, *Depth, *err)
EndProcedure

Procedure.l r8b_execute(*InFileName.s, *OutFilename.s, OutRate.l, OutBitDepth.l, OutQuality.l, Preallocate.l, *CancelFlag.l, *TR8BCallback, *p.l, *err.TR8BError)
  ProcedureReturn CallCFunction(r8bLib, "r8b_execute", *InFileName, *OutFilename, OutRate, OutBitDepth, OutQuality, Preallocate, *CancelFlag, *TR8BCallback, *p, *err)
EndProcedure

Procedure.l r8b_executeMem(*InFormat.TR8BInputFormat, *OutBuffer.l, OutLength.l, OutRate.l, OutBitDepth.l, OutQuality.l, *CancelFlag.l, *TR8BCallback, *p.l, *err.TR8BError, *ActualOut.l)
  ProcedureReturn CallCFunction(r8bLib, "r8b_executeMem", *InFormat, *OutBuffer, OutLength, OutRate, OutBitDepth, OutQuality, *CancelFlag, *TR8BCallback, *p, *err, *ActualOut) 
EndProcedure

Procedure.l r8b_execute2(*InFileName, *OutFilename, OutRate.l, OutBitDepth.l, OutQuality.l, Preallocate.l, OutRateReal.d, *CancelFlag.l, *TR8BCallback, *p.l, *err.TR8BError)
  ProcedureReturn CallCFunction(r8bLib, "r8b_execute", *InFileName, *OutFilename, OutRate, OutBitDepth, OutQuality, Preallocate, OutRateReal, *CancelFlag, *TR8BCallback, *p, *err)
EndProcedure

Procedure.l r8b_executeMem2(*InFormat.TR8BInputFormat, *OutBuffer.l, OutLength.l, OutRate.d, OutBitDepth.l, OutQuality.l, *CancelFlag.l, *TR8BCallback, *p.l, *err.TR8BError, *ActualOut.l)
  ProcedureReturn CallCFunction(r8bLib, "r8b_executeMem", *InFormat, *OutBuffer, OutLength, OutRate, OutBitDepth, OutQuality, *CancelFlag, *TR8BCallback, *p, *err, *ActualOut) 
EndProcedure
And a quick example program:

Code: Select all

EnableExplicit

IncludeFile "r8b.pbi"

Init_r8b()                ; Initialise the r8b library

Define filename$
Define SR.l, Depth.l
Define r8bErr.TR8BError

filename$ = OpenFileRequester("Open WAV file", "", "*.WAV|*.WAV", 0)

r8b_getWAVInfo(@filename$, @SR, @Depth, r8bErr)

If r8bErr\WasError = 0        ; Did an error occur?
  
  ; No, display sample details
  
  Debug "Sample rate: " + Str(SR)
  Debug "Depth: " + Str(Depth)
  
Else
  
  ; Yes, display the error
  
  Debug PeekS(@r8bErr\ErrMsg)
  
EndIf
Kind regards,

Francis.
THCM
Enthusiast
Enthusiast
Posts: 276
Joined: Fri Apr 25, 2003 5:06 pm
Location: Gummersbach - Germany
Contact:

Post by THCM »

Thx for the nice includes!

I have a little problem. When I resample an 8 Bit sample from a Protracker Module I'll only get a distorted sound:

Code: Select all

*SamplePointer = *WorkSpace + (#ModPatternData + ((LastUsedPattern+1) * #ModPatternSize)) + SampleStarts(t)

InFormat\Buffer   = *SamplePointer
InFormat\Rate     = 8363
InFormat\BitDepth = 8
InFormat\Channels = 1
InFormat\IEEE     = 0 
InFormat\Len      = SampleLengths(t)

r8b_executeMem(InFormat, *ReSampleMem, $20000, 4131, 8, #TR8B_QUALITY_VERYHIGH, @CancelFlag, 0, 0, Error, @ActualSize)
*ReSampleMem holds the correct number of samples (ActualSize). With the r8brain gui everything works OK. Any clue?
The Human Code Machine / Masters' Design Group
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

Post by Dreamland Fantasy »

Hi there,

Just looking at your code quickly, should you not have a * prefixed to InFormat? I.e.

Code: Select all

*InFormat\Buffer = *SamplePointer
or

Code: Select all

r8b_executeMem(*InFormat, *ReSampleMem, $20000, 4131, 8, #TR8B_QUALITY_VERYHIGH, @CancelFlag, 0, 0, Error, @ActualSize) 
It's been a while since I've looked at the r8b.dll stuff so I will need to refresh my memory.

Kind regards,

Francis.
THCM
Enthusiast
Enthusiast
Posts: 276
Joined: Fri Apr 25, 2003 5:06 pm
Location: Gummersbach - Germany
Contact:

Post by THCM »

Thx for the fast reply Francis. I'll check later when I'm back at home.
The Human Code Machine / Masters' Design Group
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

Post by Dreamland Fantasy »

Another thing to check is whether the sample is signed or unsigned, i.e. does it have a range of 0 to 255 or -127 to 128.

You may need to pre-process the sample and add an offset.

Kind regards,

Francis.
THCM
Enthusiast
Enthusiast
Posts: 276
Joined: Fri Apr 25, 2003 5:06 pm
Location: Gummersbach - Germany
Contact:

Post by THCM »

Hi Francis,

it's not the prefix thing and as far as I know, Protracker modules have signed 8 bit samples stored and I think that r8brain works unsigned too. I saved a sample from the .mod file and used the gui to downsample and everthing worked as it should.

Any other clue?

Yours sincerely, Uwe
The Human Code Machine / Masters' Design Group
User avatar
Dreamland Fantasy
Enthusiast
Enthusiast
Posts: 335
Joined: Fri Jun 11, 2004 9:35 pm
Location: Glasgow, UK
Contact:

Post by Dreamland Fantasy »

It's kind of hard to debug without having your source and example files in front of me, so to speak.

Is the calculation for your sample pointer correct?

Kind regards,

Francis.
KarLKoX
Enthusiast
Enthusiast
Posts: 681
Joined: Mon Oct 06, 2003 7:13 pm
Location: France
Contact:

Post by KarLKoX »

Protrackers samples datas are stored in bigendian order.
"Qui baise trop bouffe un poil." P. Desproges

http://karlkox.blogspot.com/
THCM
Enthusiast
Enthusiast
Posts: 276
Joined: Fri Apr 25, 2003 5:06 pm
Location: Gummersbach - Germany
Contact:

Post by THCM »

@KarlKox I know that Amiga .mod files store the sample data as words, but all samples are in 8 bit, so where's the Problem? How do I have to rearrange the sample data?
The Human Code Machine / Masters' Design Group
THCM
Enthusiast
Enthusiast
Posts: 276
Joined: Fri Apr 25, 2003 5:06 pm
Location: Gummersbach - Germany
Contact:

Post by THCM »

I found it! All samples in the Amiga .mod file are signed and r8brain needs signed samples to operate correct. Very confusing... I always thougt .wav files are signed too.
The Human Code Machine / Masters' Design Group
Post Reply