ogg and vorbis are delivered with PB. You can simply use
Code: Select all
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
;
; https://xiph.org/vorbis/doc/libvorbis/overview.html
; https://github.com/xiph/vorbis/blob/master/include/vorbis/codec.h
;
#OV_FALSE = -1
#OV_EOF = -2
#OV_HOLE = -3
#OV_EREAD = -128
#OV_EFAULT = -129
#OV_EIMPL = -130
#OV_EINVAL = -131
#OV_ENOTVORBIS = -132
#OV_EBADHEADER = -133
#OV_EVERSION = -134
#OV_ENOTAUDIO = -135
#OV_EBADPACKET = -136
#OV_EBADLINK = -137
#OV_ENOSEEK = -138
#OV_ECTL_RATEMANAGE_GET = $10
#OV_ECTL_RATEMANAGE_SET = $11
#OV_ECTL_RATEMANAGE_AVG = $12
#OV_ECTL_RATEMANAGE_HARD = $13
#OV_ECTL_RATEMANAGE2_GET = $14
#OV_ECTL_RATEMANAGE2_SET = $15
#OV_ECTL_LOWPASS_GET = $20
#OV_ECTL_LOWPASS_SET = $21
#OV_ECTL_IBLOCK_GET = $30
#OV_ECTL_IBLOCK_SET = $31
#OV_ECTL_COUPLING_GET = $40
#OV_ECTL_COUPLING_SET = $41
Structure ogg_stream_state Align #PB_Structure_AlignC
*body_data
body_storage.l
body_fill.l
body_returned.l
*lacing_vals
*granule_vals
lacing_storage.l
lacing_fill.l
lacing_packet.l
lacing_returned.l
header.a[282]
header_fill.i
e_o_s.i
b_o_s.i
serialno.l
pageno.l
packetno.q
granulepos.q
EndStructure
Structure ogg_page Align #PB_Structure_AlignC
*header
header_len.l
*body
body_len.l
EndStructure
Structure ogg_packet Align #PB_Structure_AlignC
*packet
bytes.l
b_o_s.l
e_o_s.l
granulepos.q
packetno.q
EndStructure
Structure oggpack_buffer Align #PB_Structure_AlignC
endbyte.l
endbit.i
*buffer
*ptr
storage.l
EndStructure
Structure vorbis_info Align #PB_Structure_AlignC
version.i
channels.i
rate.l
bitrate_upper.l
bitrate_nominal.l
bitrate_lower.l
bitrate_window.l
*codec_setup
EndStructure
Structure vorbis_comment Align #PB_Structure_AlignC
*user_comments
*comment_lengths
comments.i
*vendor
EndStructure
Structure vorbis_block Align #PB_Structure_AlignC
*pcm
opb.oggpack_buffer
lW.l
W.l
nW.l
pcmend.i
mode.i
eofflag.i
granulepos.q
sequence.q
*vd.vorbis_dsp_state
*localstore
localtop.l
localalloc.l
totaluse.l
*reap.alloc_chain
glue_bits.l
time_bits.l
floor_bits.l
res_bits.l
*internal
EndStructure
Structure vorbis_dsp_state Align #PB_Structure_AlignC
analysisp.i
*vi.vorbis_info
*pcm
*pcmret
pcm_storage.i
pcm_current.i
pcm_returned.i
preextrapolate.i
eofflag.i
lW.l
W.l
nW.l
centerW.l
granulepos.q
sequence.q
glue_bits.q
time_bits.q
floor_bits.q
res_bits.q
*backend_state
EndStructure
ImportC "ogg.lib"
; Encoding related
ogg_stream_packetin.i(*os.ogg_stream_state, *op.ogg_packet)
ogg_stream_pageout(*os.ogg_stream_state, *og.ogg_page)
ogg_stream_flush.i(*os.ogg_stream_state, *og.ogg_page)
; General
ogg_stream_clear(*os.ogg_stream_state)
ogg_stream_init.i(*os.ogg_stream_state, serialno.i)
ogg_page_eos.i(*og.ogg_page)
EndImport
ImportC "vorbisfile.lib"
; Functions used by both decode And encode
vorbis_block_clear(*vb.vorbis_block)
vorbis_block_init(*v.vorbis_dsp_state, *vb.vorbis_block)
vorbis_dsp_clear(*v.vorbis_dsp_state)
vorbis_granule_time.d(*v.vorbis_dsp_state, granulepos.l)
vorbis_info_blocksize(*vi.vorbis_info, zo.i)
vorbis_info_clear(*vi.vorbis_info)
vorbis_info_init(*vi.vorbis_info)
vorbis_version_string.i()
; Decoding
vorbis_packet_blocksize.l(*vi.vorbis_info, *op.ogg_packet)
vorbis_synthesis.i(*vb.vorbis_block , *op.ogg_packet)
vorbis_synthesis_blockin.i(*v.vorbis_dsp_state , *vb.vorbis_block)
vorbis_synthesis_halfrate.i(*v.vorbis_info, flag.i)
vorbis_synthesis_headerin.i(*vi.vorbis_info, *vc.vorbis_comment, *op.ogg_packet)
vorbis_synthesis_idheader.i(*op.ogg_packet)
vorbis_synthesis_init.i(*v.vorbis_dsp_state, *vi.vorbis_info)
vorbis_synthesis_lapout.i(*v.vorbis_dsp_state, *pcm)
vorbis_synthesis_pcmout.i(*v.vorbis_dsp_state, *pcm)
vorbis_synthesis_read.i(*v.vorbis_dsp_state, samples.i)
vorbis_synthesis_restart.i(*v.vorbis_dsp_state)
vorbis_synthesis_trackonly.i(*vb.vorbis_block , *op.ogg_packet)
; Encoding
vorbis_analysis(*vb.vorbis_block, *op.ogg_packet)
vorbis_analysis_blockout.i(*v.vorbis_dsp_state, *vb.vorbis_block)
vorbis_analysis_buffer.i(*v.vorbis_dsp_state, vals.i)
vorbis_analysis_headerout.i(*v.vorbis_dsp_state, *vc.vorbis_comment, *op.ogg_packet, *op_comm.ogg_packet, *op_code.ogg_packet)
vorbis_analysis_init.i(*v.vorbis_dsp_state, *vi.vorbis_info)
vorbis_analysis_wrote(*v.vorbis_dsp_state, vals.i)
vorbis_bitrate_addblock(*vbvorbis_block)
vorbis_bitrate_flushpacket(*vd.vorbis_dsp_state, *op.ogg_packet)
vorbis_encode_ctl.i(*vi.vorbis_info, request.i, *arg)
vorbis_encode_init.i(*vi.vorbis_info, channels.l, rate.l, max_bitrate.l, nominal_bitrate.l, min_bitrate.l)
vorbis_encode_init_vbr.i(*vi.vorbis_info, channels.l, rate.l, base_quality.f)
vorbis_encode_setup_init.i(*vi.vorbis_info)
vorbis_encode_setup_managed.i(*vi.vorbis_info, channels.l, rate.l, max_bitrate.l, nominal_bitrate.l, min_bitrate.l)
vorbis_encode_setup_vbr.i(*vi.vorbis_info, channels.l, rate.l, base_quality.f)
; Metadata
vorbis_comment_add(*vc.vorbis_comment, comment.p-ascii)
vorbis_comment_add_tag(*vc.vorbis_comment, tag.p-ascii, contents.p-ascii)
vorbis_comment_clear(*vc.vorbis_comment)
vorbis_comment_init(*vc.vorbis_comment)
vorbis_comment_query.i(*vc.vorbis_comment, tag.p-ascii, count.i)
vorbis_comment_query_count.i(*vc.vorbis_comment, tag.p-ascii)
vorbis_commentheader_out.i(*vc.vorbis_comment, *op.ogg_packet)
EndImport
Procedure.s Vorbis_GetErrorText(Error.i)
Protected Result$
Select Error
Case #OV_FALSE : Result$ = "OV_FALSE"
Case #OV_EOF : Result$ = "OV_EOF"
Case #OV_HOLE : Result$ = "OV_HOLE"
Case #OV_EREAD : Result$ = "OV_EREAD: A read from media returned an error."
Case #OV_EFAULT : Result$ = "OV_EFAULT: Internal logic fault; indicates a bug or heap/stack corruption."
Case #OV_EIMPL : Result$ = "OV_EIMPL: The bitstream makes use of a feature not implemented in this library version."
Case #OV_EINVAL : Result$ = "OV_EINVAL: Invalid argument value."
Case #OV_ENOTVORBIS : Result$ = "OV_ENOTVORBIS: Bitstream/page/packet is not Vorbis data."
Case #OV_EBADHEADER : Result$ = "OV_EBADHEADER: Invalid Vorbis bitstream header."
Case #OV_EVERSION : Result$ = "OV_EVERSION: Vorbis version mismatch."
Case #OV_ENOTAUDIO : Result$ = "OV_ENOTAUDIO: Packet data submitted to vorbis_synthesis is not audio data."
Case #OV_EBADPACKET : Result$ = "OV_EBADPACKET: Invalid packet submitted to vorbis_synthesis."
Case #OV_EBADLINK : Result$ = "OV_EBADLINK: Invalid stream section supplied to libvorbis/libvorbisfile, or the requested link is corrupt."
Case #OV_ENOSEEK : Result$ = "OV_ENOSEEK: Bitstream is not seekable."
Default : Result$ = "OV unknown error: " + Str(Error)
EndSelect
ProcedureReturn Result$
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
; https://github.com/xiph/vorbis/blob/master/examples/encoder_example.c
; WAV file wich works (44100 Hz PCM 16bit Stereo)
; http://www.music.helsinki.fi/tmt/opetus/uusmedia/esim/a2002011001-e02.wav
#Read = 1024
Define *readbuffer
Define os.ogg_stream_state
Define og.ogg_page
Define op.ogg_packet
Define vi.vorbis_info
Define vc.vorbis_comment
Define vd.vorbis_dsp_state
Define vb.vorbis_block
Define header.ogg_packet
Define header_comm.ogg_packet
Define header_code.ogg_packet
Define.i eos, ret
Define.i i, founddata
Define result.i, bytes.i, *floatbuffer
Define Filename$, InFile.i, OutFile.i, *fptr, WVal.u
Filename$ = OpenFileRequester("Choose a 44.1k WAV file", "", "WAV|*.wav", 0)
If Filename$
InFile = ReadFile(#PB_Any, Filename$)
If InFile
*readbuffer = AllocateMemory(#Read * 4 + 44)
If *readbuffer
While i < 30 And Not Eof(InFile)
If ReadData(InFile, *readbuffer, 2) = 2
If PeekS(*readbuffer, 2, #PB_Ascii) = "da"
founddata = #True
ReadData(InFile, *readbuffer, 6)
Break
EndIf
EndIf
i + 1
Wend
vorbis_info_init(@vi)
; ret = vorbis_encode_init_vbr(@vi, 2, 44100, 0.4)
;
; ret = vorbis_encode_setup_managed(@vi, 2, 44100, -1, 128000, -1)
; ret = vorbis_encode_ctl(@vi, #OV_ECTL_RATEMANAGE2_SET, #Null)
; ret = vorbis_encode_setup_init(@vi)
ret = vorbis_encode_init_vbr(@vi, 2, 44100, 0.1)
If Not ret
vorbis_comment_init(@vc)
vorbis_comment_add_tag(@vc, "ENCODER", "OggVorbis.pbi")
vorbis_analysis_init(@vd, @vi)
vorbis_block_init(@vd, @vb)
RandomSeed(Date())
ogg_stream_init(@os, Random(100000000))
vorbis_analysis_headerout(@vd, @vc, @header, @header_comm, @header_code)
ogg_stream_packetin(@os, @header)
ogg_stream_packetin(@os, @header_comm)
ogg_stream_packetin(@os, @header_code)
OutFile = CreateFile(#PB_Any, GetPathPart(Filename$) + GetFilePart(Filename$, #PB_FileSystem_NoExtension) + ".ogg")
If OutFile
While Not eos
result = ogg_stream_flush(@os, @og)
If result = 0
Break
EndIf
WriteData(OutFile, og\header, og\header_len)
WriteData(OutFile, og\body, og\body_len)
Wend
While Not eos
bytes = ReadData(InFile, *readbuffer, #Read * 4)
If bytes = 0
vorbis_analysis_wrote(@vd, 0)
Else
*floatbuffer = vorbis_analysis_buffer(@vd, #Read)
For i = 0 To bytes/4 - 1
*fptr = PeekI(*floatbuffer)
WVal = (PeekA(*readbuffer + i * 4 + 1) << 8) | PeekA(*readbuffer + i * 4)
PokeF(*fptr + i * SizeOf(float), WVal / 32768)
*fptr = PeekI(*floatbuffer + SizeOf(Integer))
WVal = (PeekA(*readbuffer + i * 4 + 3) << 8) | PeekA(*readbuffer + i * 4 + 2)
PokeF(*fptr + i * SizeOf(float), WVal / 32768)
Next i
vorbis_analysis_wrote(@vd, i)
EndIf
While vorbis_analysis_blockout(@vd, @vb) = 1
vorbis_analysis(@vb, #Null)
vorbis_bitrate_addblock(@vb)
While vorbis_bitrate_flushpacket(@vd, @op)
ogg_stream_packetin(@os, @op)
While Not eos
result = ogg_stream_pageout(@os, @og)
If result = 0
Break
EndIf
WriteData(OutFile, og\header, og\header_len)
WriteData(OutFile, og\body, og\body_len)
If ogg_page_eos(@og)
eos = #True
EndIf
Wend
Wend
Wend
Wend
ogg_stream_clear(@os)
vorbis_block_clear(@vb)
vorbis_dsp_clear(@vd)
vorbis_comment_clear(@vc)
vorbis_info_clear(@vi)
CloseFile(OutFile)
EndIf
EndIf
FreeMemory(*readbuffer)
EndIf
CloseFile(InFile)
EndIf
EndIf
CompilerEndIf