Hello!
I would like to know if there is a way to encode and write an audio file? Is there a framework for PB? I want to write mp3 or ogg files...
Thank you and have a nice day.
Writing an audio file?
Re: Writing an audio file?
A WAV file is no problem (search for RIFF here in the forum)
MP3 needs an external lib
Ogg should be possible if you import the needed functions with Import from
vorbisfile.lib and ogg.lib
MP3 needs an external lib
Ogg should be possible if you import the needed functions with Import from
vorbisfile.lib and ogg.lib
Re: Writing an audio file?
Thank you infratec. It helps for a wav file. Do you know the name of an mp3 lib? And where are the vorbisfile.lib and ogg.lib? And where is the doc for them? Do they come with PB software?infratec wrote:A WAV file is no problem (search for RIFF here in the forum)
MP3 needs an external lib
Ogg should be possible if you import the needed functions with Import from
vorbisfile.lib and ogg.lib
Thank you.
Re: Writing an audio file?
Name of a mp3 lib ??? LAME
ogg and vorbis are delivered with PB. You can simply use
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
Last edited by infratec on Thu Mar 26, 2020 12:17 pm, edited 1 time in total.
Re: Writing an audio file?
Thank you very very much. I'm going to take a look of this.
Have a great day.
Have a great day.
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Writing an audio file?
Others have worked on similar stuff in the past, no doubt it would help to see their code:
Generate sfxr Sound Effects, in-game
QBPlay_1.5.zip (Links to the RS BASIC Backups List)
Generate sfxr Sound Effects, in-game
QBPlay_1.5.zip (Links to the RS BASIC Backups List)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Addict
- Posts: 1443
- Joined: Wed Nov 12, 2008 5:01 pm
- Location: Russia
Re: Writing an audio file?
Possible use acm functions. https://docs.microsoft.com/en-us/window ... -functionsinfratec wrote:MP3 needs an external lib
Re: Writing an audio file?
I extended and corrected my stuff above.
It includes now the example from the vorbis site.
In general it works, but ....
I don't know why the sound is messy in the ogg file.
It includes now the example from the vorbis site.
In general it works, but ....
I don't know why the sound is messy in the ogg file.
Re: Writing an audio file?
Ok. I have a work now. I am going to take a look at this code.
Thank you. Have a nice day!
Thank you. Have a nice day!