Re: PortAudio for PB
Posted: Sun Jul 02, 2017 1:40 pm
For better quality you probably need to upsample to 16 bit / 22050 Hz (or 44100 Hz) and add a low pass filter.SeregaZ wrote:yes. your code sounds better, but anyway have hiss.
http://www.purebasic.com
https://www.purebasic.fr/english/
For better quality you probably need to upsample to 16 bit / 22050 Hz (or 44100 Hz) and add a low pass filter.SeregaZ wrote:yes. your code sounds better, but anyway have hiss.
Try this 4 to 16 bit conversion.SeregaZ wrote:probably false alarm. we start think it is some custom modification of GEMS driver. and probably it is ADPCM, not PCM. or maybe something else. probably i will lay as you procedure do. just for know how it sounds, without record options. cursed MK developersmake so dificult for me
Code: Select all
Procedure PCM4to16(*src.Ascii, *dst.Unicode, cnt)
Protected Dim vt.u(15)
PokeQ(@vt(00),$0400020001000000)
PokeQ(@vt(04),$4000200010000800)
PokeQ(@vt(08),$FC00FE00FF008000)
PokeQ(@vt(12),$C000E000F000F800)
While cnt
*dst\u = vt(*src\a&$f) : *dst+2
*dst\u = vt(*src\a>>4) : *dst+2
*src + 1 : cnt - 1
Wend
EndProcedure
Procedure WavHeaderCreation(*memst)
;RIFF
PokeB(*memst, $52):PokeB(*memst+1, $49):PokeB(*memst+2,$46):PokeB(*memst+3, $46)
;WAVE
PokeB(*memst+8, $57):PokeB(*memst+9, $41):PokeB(*memst+10,$56):PokeB(*memst+11, $45)
;fmt
PokeB(*memst+12, $66):PokeB(*memst+13, $6d):PokeB(*memst+14,$74):PokeB(*memst+15, $20)
;header size
PokeB(*memst+16, $10)
;PCM 01
PokeB(*memst+20, $01)
;mono stereo
PokeB(*memst+22, $01)
;1
PokeB(*memst+32, $01)
;bit
PokeB(*memst+34, $10)
;data
PokeB(*memst+36, $64)
PokeB(*memst+37, $61)
PokeB(*memst+38, $74)
PokeB(*memst+39, $61)
EndProcedure
inpval.b
If ReadFile(0, "D:\Samples.bin")
length = Lof(0)
*sndsource = AllocateMemory(length)
If *sndsource
ReadData(0, *sndsource, length)
EndIf
CloseFile(0)
EndIf
If *sndsource
*snddest = AllocateMemory(length*4+44)
If *snddest
WavHeaderCreation(*snddest)
;size
PokeL(*snddest + 4, length*4+40)
PokeL(*snddest + 40, length*4)
;kbs
PokeL(*snddest + 24, 6500)
PokeL(*snddest + 28, 6500)
PCM4to16(*sndsource, *snddest+44, length)
EndIf
EndIf
;sndPlaySound_(*snddest,#SND_MEMORY | #SND_ASYNC | #SND_NODEFAULT)
;Delay(5000)
If CreateFile(0, "D:\demo.wav")
WriteData(0, *snddest, length*4+44)
CloseFile(0)
EndIf
2017-07-02 22:45:20 ValleyBell http://vgmrips.net/misc/MK3_DACME.asm disassembled/commented DAC playback routines for MK3
2017-07-02 22:45:38 ValleyBell It allows for 8-bit LPCM or 4-bit DPCM.
2017-07-02 22:45:53 ValleyBell (DPCM, *not* ADPCM)
Code: Select all
dc.b 00H, 01H, 03H, 07H, 0DH, 15H, 1FH, 2BH
dc.b -00H,-01H,-03H,-07H,-0DH,-15H,-1FH,-2BH
not understand what i need do sure, but i start making +- array's values to base value $80As for how the data is compressed, lemme explain that real quick: First, it is a lossy compression. So if you recompress a PCM sample this way, you will lose precision in data. Anyway, what happens is that each compressed data is seperated into nybbles (1 4-bit section of a byte). This first nybble of data is read, and used as an index to a table containing the following data: 0,1,2,4,8,$10,$20,$40,$80,$FF,$FE,$FC,$F8,$F0,$E0,$C0. So if the nybble were equal to F, it'd extract $C0 from the tale. If it were 8, it would extract $80 from the table. Etc. etc. Anyway, there is also another byte of data that we'll call 'd'. At the start of decompression, d is $80. What happens is that d is then added to the data extracted from the table using the nybble. So if the nybble were 4, the 8 would be extracted from the table, then added to d, which is $80, resulting in $88. This result is then put bank into d, then fed into the YM2612 for processing. Then the next nybble is read, the data is extracted from the table, then is added to d (remember, d is now changed because of the previous operation), then is put bank into d, then is fed into the YM2612. This process is repeated until the number of bytes as defined in the table above are read and decompressed.
Code: Select all
;{
Macro SetBit(Var, Bit)
Var | (Bit)
EndMacro
Macro ClearBit(Var, Bit)
Var & (~(Bit))
EndMacro
Macro TestBit(Var, Bit)
Bool(Var & (Bit))
EndMacro
Macro NumToBit(Num)
(1<<(Num))
EndMacro
Macro GetBits(Var, StartPos, EndPos)
((Var>>(StartPos))&(NumToBit((EndPos)-(StartPos)+1)-1))
EndMacro
;}
;dc.b 00H, 01H, 03H, 07H, 0DH, 15H, 1FH, 2BH
;dc.b -00H,-01H,-03H,-07H,-0DH,-15H,-1FH,-2BH
Global Dim pikarray.b(15)
pikarray(0) = 0
pikarray(1) = 1
pikarray(2) = 3
pikarray(3) = 7
pikarray(4) = $D
pikarray(5) = $15
pikarray(6) = $1F
pikarray(7) = $2B
pikarray(8) = 0
pikarray(9) = -1
pikarray(10) = -3
pikarray(11) = -7
pikarray(12) = -$D
pikarray(13) = -$15
pikarray(14) = -$1F
pikarray(15) = -$2B
Procedure WavHeaderCreation(*memst)
;RIFF
PokeB(*memst, $52):PokeB(*memst+1, $49):PokeB(*memst+2,$46):PokeB(*memst+3, $46)
;WAVE
PokeB(*memst+8, $57):PokeB(*memst+9, $41):PokeB(*memst+10,$56):PokeB(*memst+11, $45)
;fmt
PokeB(*memst+12, $66):PokeB(*memst+13, $6d):PokeB(*memst+14,$74):PokeB(*memst+15, $20)
;header size
PokeB(*memst+16, $10)
;PCM 01
PokeB(*memst+20, $01)
;mono stereo
PokeB(*memst+22, $01)
;1
PokeB(*memst+32, $01)
;bit
PokeB(*memst+34, $08)
;data
PokeB(*memst+36, $64)
PokeB(*memst+37, $61)
PokeB(*memst+38, $74)
PokeB(*memst+39, $61)
EndProcedure
inpval.a
first.b
second.b
forwrite.b = $80
If ReadFile(0, "D:\Samples.bin")
length = Lof(0)
*sndsource = AllocateMemory(length)
If *sndsource
ReadData(0, *sndsource, length)
EndIf
CloseFile(0)
EndIf
If *sndsource
*snddest = AllocateMemory(length*2+44)
If *snddest
WavHeaderCreation(*snddest)
;size
PokeL(*snddest + 4, length*2+40)
PokeL(*snddest + 40, length*2)
;kbs
PokeL(*snddest + 24, 6500)
PokeL(*snddest + 28, 6500)
For i = 0 To length
inpval = PeekA(*sndsource+i)
first = GetBits(inpval, 0, 3) ; get %0000xxxx
second = GetBits(inpval, 4, 7) ; get %xxxx0000
;first * 16
;second * 16
;first = pikarray(first)
;second = pikarray(second)
forwrite = forwrite + pikarray(first)
PokeB(*snddest+44+(i*2), forwrite)
forwrite = forwrite + pikarray(second)
PokeB(*snddest+45+(i*2), forwrite)
Next
EndIf
EndIf
;sndPlaySound_(*snddest,#SND_MEMORY | #SND_ASYNC | #SND_NODEFAULT)
;Delay(5000)
If CreateFile(0, "D:\demo.wav")
WriteData(0, *snddest, length*2+44)
CloseFile(0)
EndIf
Code: Select all
Procedure.l limit(l.l)
If l > 127
ProcedureReturn 127
ElseIf l < -128
ProcedureReturn -128
Else
ProcedureReturn l
EndIf
EndProcedure
Procedure PCM4to16(*src.Ascii, *dst.Byte, cnt)
Protected Dim vt.b(15)
Protected s.l
PokeQ(@vt(00),$2b1f150d07030100)
PokeQ(@vt(08),$d5e1ebf3f9fdff00)
While cnt
s + vt(*src\a&$f) : *dst\b = $80!limit(s) : *dst+1
s + vt(*src\a>>4) : *dst\b = $80!limit(s) : *dst+1
*src + 1 : cnt - 1
Wend
EndProcedure
Procedure WavHeaderCreation(*memst)
;RIFF
PokeB(*memst, $52):PokeB(*memst+1, $49):PokeB(*memst+2,$46):PokeB(*memst+3, $46)
;WAVE
PokeB(*memst+8, $57):PokeB(*memst+9, $41):PokeB(*memst+10,$56):PokeB(*memst+11, $45)
;fmt
PokeB(*memst+12, $66):PokeB(*memst+13, $6d):PokeB(*memst+14,$74):PokeB(*memst+15, $20)
;header size
PokeB(*memst+16, $10)
;PCM 01
PokeB(*memst+20, $01)
;number of channels
PokeB(*memst+22, $01)
;block align
PokeB(*memst+32, $01)
;bits per sample
PokeB(*memst+34, $08)
;data
PokeB(*memst+36, $64)
PokeB(*memst+37, $61)
PokeB(*memst+38, $74)
PokeB(*memst+39, $61)
EndProcedure
inpval.b
If ReadFile(0, "D:\Samples.bin")
length = Lof(0)
*sndsource = AllocateMemory(length)
If *sndsource
ReadData(0, *sndsource, length)
EndIf
CloseFile(0)
EndIf
If *sndsource
*snddest = AllocateMemory(length*2+44)
If *snddest
WavHeaderCreation(*snddest)
;size
PokeL(*snddest + 4, length*2+40)
PokeL(*snddest + 40, length*2)
;sample rate
PokeL(*snddest + 24, 6500)
; byte rate
PokeL(*snddest + 28, 6500)
PCM4to16(*sndsource, *snddest+44, length)
EndIf
EndIf
;sndPlaySound_(*snddest,#SND_MEMORY | #SND_ASYNC | #SND_NODEFAULT)
;Delay(5000)
If CreateFile(0, "D:\demo.wav")
WriteData(0, *snddest, length*2+44)
CloseFile(0)
EndIf
PortAudio is an open source cross platform library for streaming audio.SeregaZ wrote:why that? topic is PortAudio and we make this port audio from DPCM to PCM, that can understand PBor it was my bad language... port - it means porting?
If you don't have to worry about limiting values, you can simply start with $80 and add the values you look up.SeregaZ wrote:about limit() - it is my failt. i use bank of samples at once. it means delta of old sample comes to new one - it can make this overlimits and scratch for sound.