os dejo este codigo para convertir un archivo audio de tipo WAV en tipo Ogg-Vorbis con las funciones externas de API de libfishsound y de liboggz
El codigo usa tambien unas funciones de la librería libsndfile para cargar el archvo WAV.
Public Struct ogg_packet
packet As Pointer
bytes As Long
b_o_s As Long
e_o_s As Long
granulepos As Long
packetno As Long
End Struct
Private Const ENCODE_BLOCK_SIZE As Long = 1152
Private serialno As Long
Private b_o_s As Integer = 1
Library "libfishsound:1.3.0"
Public Struct FishSoundInfo
samplerate As Integer
channels As Integer
formatFSI As Integer
End Struct
Private Enum FISH_SOUND_UNKNOWN = 0, FISH_SOUND_VORBIS
Private Const FISH_SOUND_ENCODE_ As Integer = &20
' FishSound * fish_sound_new (int mode, FishSoundInfo * fsinfo)
' Instantiate a new FishSound* handle.
Private Extern fish_sound_new(mode As Integer, FSInfo As FishSoundInfo) As Pointer
' int fish_sound_set_encoded_callback (FishSound * fsound, FishSoundEncoded encoded, void * user_data)
' Set the callback for libfishsound to call when it has a block of encoded data ready.
Private Extern fish_sound_set_encoded_callback(FS As Pointer, FishSoundEncoded As Pointer, data As Pointer) As Integer
' int fish_sound_set_interleave (FishSound * fsound, int interleave)
' Set the PCM format used by a FishSound object. DEPRECATED FUNCTION.
Private Extern fish_sound_set_interleave(FS As Pointer, interleave As Integer) As Integer
' int fish_sound_comment_add_byname (FishSound * fsound, const char * name, const char * value)
' Add a comment by name and value.
Private Extern fish_sound_comment_add_byname(FS As Pointer, name As String, value As String) As Integer
' long fish_sound_encode (FishSound * fsound, float ** pcm, long frames)
' Encode a block of audio. DEPRECATED FUNCTION.
Private Extern fish_sound_encode(FS As Pointer, pcm As Pointer, frames As Long) As Long
' long fish_sound_flush (FishSound * fsound)
' Flush any internally buffered data, forcing encode.
Private Extern fish_sound_flush(FS As Pointer) As Long
' long fish_sound_get_frameno (FishSound * fsound)
' Query the current frame number of a FishSound object.
Private Extern fish_sound_get_frameno(FS As Pointer) As Long
' int fish_sound_delete (FishSound * fsound)
' Delete a FishSound object.
Private Extern fish_sound_delete(FS As Pointer) As Integer
Library "libsndfile:1.0.25"
Public Struct SF_INFO
frames As Long
samplerate As Integer
channels As Integer
formatI As Integer
sections As Integer
seekable As Integer
End Struct
Private Const SFM_READ As Integer = 16
' SNDFILE * sf_open (const char *path, int mode, SF_INFO *sfinfo)
' Open the specified file for read, write or both.
Private Extern sf_open(path As String, mode As Integer, SFinf As SF_INFO) As Pointer
' sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames)
' Function for reading the data chunk in terms of frames. Passes data in the native float format.
Private Extern sf_readf_float(sndfile As Pointer, ptr As Single[], frames As Long) As Long
' int sf_close (SNDFILE *sndfile)
' Close the SNDFILE and clean up all memory allocations associated with this file.
Private Extern sf_close(sndfile As Pointer) As Integer
Library "liboggz:2.6.0"
Private Const OGGZ_WRITE As Integer = 1
' OGGZ * oggz_open (const char * filename, int flags)
' Open an Ogg file, creating an OGGZ handle for it.
Private Extern oggz_open(filename As String, flags As Integer) As Pointer
' long oggz_serialno_new (OGGZ * oggz)
' Request a new serialno, as required for a new stream.
Private Extern oggz_serialno_new(OGG As Pointer) As Long
' long oggz_run (OGGZ * oggz)
' Run an OGGZ until completion, or error.
Private Extern oggz_run(OGG As Pointer) As Long
' int oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, int * guard)
' Add a packet to \a oggz's packet queue.
Private Extern oggz_write_feed(OGGZ As Pointer, ogg_p As Ogg_packet, ser As Long, flushI As Integer, guard As Pointer) As Integer
' int oggz_close (OGGZ * oggz)
' Close an OGGZ handle.
Private Extern oggz_close(OGG As Pointer) As Integer
Public Sub Main()
Dim fileWAV, fileOGG As String
Dim snd, oggz, fsound As Pointer
Dim sfinfo As New SF_INFO
Dim fsinfo As New FishSoundInfo
Dim formato As Integer
Dim pcm As New Single[2048]
formato = FISH_SOUND_VORBIS
fileWAV = "/ruta/del/fichero.wav"
fileOGG = "/ruta/del/futuro/file.ogg"
snd = sf_open(fileWAV, SFM_READ, sfinfo)
If IsNull(snd) Then Error.Raise("Impossible abrir el fichero " & fileWAV & " !")
oggz = oggz_open(fileOGG, OGGZ_WRITE)
If IsNull(oggz) Then Error.Raise("Impossible abrir el fichero para escribir !")
serialno = oggz_serialno_new(oggz)
fsinfo.channels = sfinfo.channels
fsinfo.samplerate = sfinfo.samplerate
fsinfo.formatFSI = formato
fsound = fish_sound_new(FISH_SOUND_ENCODE_, fsinfo)
''''''
fish_sound_set_encoded_callback(fsound, encoded, oggz)
''''''
fish_sound_set_interleave(fsound, 1)
fish_sound_comment_add_byname(fsound, "Encoder", "fishsound-encode")
While sf_readf_float(snd, pcm, ENCODE_BLOCK_SIZE) > 0
fish_sound_encode(fsound, pcm.data, ENCODE_BLOCK_SIZE)
oggz_run(oggz)
Wend
fish_sound_flush(fsound)
oggz_run(oggz)
' Al terminar:
oggz_close(oggz)
fish_sound_delete(fsound)
sf_close(snd)
End
Private Function encoded(fsound As Pointer, buf As Pointer, bytes As Long, user_data As Pointer) As Integer
Dim err As Integer
Dim ogp As New Ogg_packet
Dim oggz As Pointer
ogp.packet = buf
ogp.bytes = bytes
ogp.b_o_s = b_o_s
ogp.e_o_s = 0
ogp.granulepos = fish_sound_get_frameno(fsound)
ogp.packetno = -1
err = oggz_write_feed(user_data, ogp, serialno, 0, 0)
If (err) Then Print "err: "; err
b_o_s = 0
Return 0
End
packet As Pointer
bytes As Long
b_o_s As Long
e_o_s As Long
granulepos As Long
packetno As Long
End Struct
Private Const ENCODE_BLOCK_SIZE As Long = 1152
Private serialno As Long
Private b_o_s As Integer = 1
Library "libfishsound:1.3.0"
Public Struct FishSoundInfo
samplerate As Integer
channels As Integer
formatFSI As Integer
End Struct
Private Enum FISH_SOUND_UNKNOWN = 0, FISH_SOUND_VORBIS
Private Const FISH_SOUND_ENCODE_ As Integer = &20
' FishSound * fish_sound_new (int mode, FishSoundInfo * fsinfo)
' Instantiate a new FishSound* handle.
Private Extern fish_sound_new(mode As Integer, FSInfo As FishSoundInfo) As Pointer
' int fish_sound_set_encoded_callback (FishSound * fsound, FishSoundEncoded encoded, void * user_data)
' Set the callback for libfishsound to call when it has a block of encoded data ready.
Private Extern fish_sound_set_encoded_callback(FS As Pointer, FishSoundEncoded As Pointer, data As Pointer) As Integer
' int fish_sound_set_interleave (FishSound * fsound, int interleave)
' Set the PCM format used by a FishSound object. DEPRECATED FUNCTION.
Private Extern fish_sound_set_interleave(FS As Pointer, interleave As Integer) As Integer
' int fish_sound_comment_add_byname (FishSound * fsound, const char * name, const char * value)
' Add a comment by name and value.
Private Extern fish_sound_comment_add_byname(FS As Pointer, name As String, value As String) As Integer
' long fish_sound_encode (FishSound * fsound, float ** pcm, long frames)
' Encode a block of audio. DEPRECATED FUNCTION.
Private Extern fish_sound_encode(FS As Pointer, pcm As Pointer, frames As Long) As Long
' long fish_sound_flush (FishSound * fsound)
' Flush any internally buffered data, forcing encode.
Private Extern fish_sound_flush(FS As Pointer) As Long
' long fish_sound_get_frameno (FishSound * fsound)
' Query the current frame number of a FishSound object.
Private Extern fish_sound_get_frameno(FS As Pointer) As Long
' int fish_sound_delete (FishSound * fsound)
' Delete a FishSound object.
Private Extern fish_sound_delete(FS As Pointer) As Integer
Library "libsndfile:1.0.25"
Public Struct SF_INFO
frames As Long
samplerate As Integer
channels As Integer
formatI As Integer
sections As Integer
seekable As Integer
End Struct
Private Const SFM_READ As Integer = 16
' SNDFILE * sf_open (const char *path, int mode, SF_INFO *sfinfo)
' Open the specified file for read, write or both.
Private Extern sf_open(path As String, mode As Integer, SFinf As SF_INFO) As Pointer
' sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames)
' Function for reading the data chunk in terms of frames. Passes data in the native float format.
Private Extern sf_readf_float(sndfile As Pointer, ptr As Single[], frames As Long) As Long
' int sf_close (SNDFILE *sndfile)
' Close the SNDFILE and clean up all memory allocations associated with this file.
Private Extern sf_close(sndfile As Pointer) As Integer
Library "liboggz:2.6.0"
Private Const OGGZ_WRITE As Integer = 1
' OGGZ * oggz_open (const char * filename, int flags)
' Open an Ogg file, creating an OGGZ handle for it.
Private Extern oggz_open(filename As String, flags As Integer) As Pointer
' long oggz_serialno_new (OGGZ * oggz)
' Request a new serialno, as required for a new stream.
Private Extern oggz_serialno_new(OGG As Pointer) As Long
' long oggz_run (OGGZ * oggz)
' Run an OGGZ until completion, or error.
Private Extern oggz_run(OGG As Pointer) As Long
' int oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, int * guard)
' Add a packet to \a oggz's packet queue.
Private Extern oggz_write_feed(OGGZ As Pointer, ogg_p As Ogg_packet, ser As Long, flushI As Integer, guard As Pointer) As Integer
' int oggz_close (OGGZ * oggz)
' Close an OGGZ handle.
Private Extern oggz_close(OGG As Pointer) As Integer
Public Sub Main()
Dim fileWAV, fileOGG As String
Dim snd, oggz, fsound As Pointer
Dim sfinfo As New SF_INFO
Dim fsinfo As New FishSoundInfo
Dim formato As Integer
Dim pcm As New Single[2048]
formato = FISH_SOUND_VORBIS
fileWAV = "/ruta/del/fichero.wav"
fileOGG = "/ruta/del/futuro/file.ogg"
snd = sf_open(fileWAV, SFM_READ, sfinfo)
If IsNull(snd) Then Error.Raise("Impossible abrir el fichero " & fileWAV & " !")
oggz = oggz_open(fileOGG, OGGZ_WRITE)
If IsNull(oggz) Then Error.Raise("Impossible abrir el fichero para escribir !")
serialno = oggz_serialno_new(oggz)
fsinfo.channels = sfinfo.channels
fsinfo.samplerate = sfinfo.samplerate
fsinfo.formatFSI = formato
fsound = fish_sound_new(FISH_SOUND_ENCODE_, fsinfo)
''''''
fish_sound_set_encoded_callback(fsound, encoded, oggz)
''''''
fish_sound_set_interleave(fsound, 1)
fish_sound_comment_add_byname(fsound, "Encoder", "fishsound-encode")
While sf_readf_float(snd, pcm, ENCODE_BLOCK_SIZE) > 0
fish_sound_encode(fsound, pcm.data, ENCODE_BLOCK_SIZE)
oggz_run(oggz)
Wend
fish_sound_flush(fsound)
oggz_run(oggz)
' Al terminar:
oggz_close(oggz)
fish_sound_delete(fsound)
sf_close(snd)
End
Private Function encoded(fsound As Pointer, buf As Pointer, bytes As Long, user_data As Pointer) As Integer
Dim err As Integer
Dim ogp As New Ogg_packet
Dim oggz As Pointer
ogp.packet = buf
ogp.bytes = bytes
ogp.b_o_s = b_o_s
ogp.e_o_s = 0
ogp.granulepos = fish_sound_get_frameno(fsound)
ogp.packetno = -1
err = oggz_write_feed(user_data, ogp, serialno, 0, 0)
If (err) Then Print "err: "; err
b_o_s = 0
Return 0
End