Waveplayer stereo
Posted: 06 May 2016, 14:51
Salve,
ho usato l'esempio di Glen Aidukas (la versione per file stereo) per realizzare un lettore di file wave stereo.
Il problema è che su un canale, l'audio è ok e su un canale, l'audio è disturbato.
Ho fatto la prova usando lo stesso amplificatore una volta per un canale e poi per un altro, quindi il circuito è ok.
Qualcosa non va nel codice?
Ho allegato due file audio per far capire meglio il problema.
E' un bel progetto sarebbe un peccato se non risolvo questo problema, aiutatemi
grazie.
ho usato l'esempio di Glen Aidukas (la versione per file stereo) per realizzare un lettore di file wave stereo.
Il problema è che su un canale, l'audio è ok e su un canale, l'audio è disturbato.
Ho fatto la prova usando lo stesso amplificatore una volta per un canale e poi per un altro, quindi il circuito è ok.
Qualcosa non va nel codice?
Ho allegato due file audio per far capire meglio il problema.
E' un bel progetto sarebbe un peccato se non risolvo questo problema, aiutatemi
grazie.
- Code: Select all
'===============================================================================
' Project: Wave Audio file player. (only plays wave riff PCM format)
' Play Wave format, RIFF, Mono max 44KHz/stereo max 22KHz, 8bit, PCM audio file
' Version for stereo wave files
' By: Glen Aidukas
'===============================================================================
'=====[ Compiler Directives ]===================================================
$regfile = "m1284Pdef.dat" '"m644pdef.dat"
$crystal = 18432000 ' 18.432 MHz
$baud = 38400
$hwstack = 100
$swstack = 100
$framesize = 100
'-------------------------------------------------------------------------------
'=====[ Includes ]==============================================================
$include "Config_MMC.bas" ' Load SD/MMC code and config
$include "Config_AVR-DOS.BAS" ' Load FAT File system code
'$include "WavePlayerLib.bas" ' PlayWaveFile code.
'-------------------------------------------------------------------------------
Const Vsw = "2.1"
Const Wp_bufsize = 250 ' Size of each (A&B) buffers
Const Wp_statusnoerrors = 0 ' No errors
Const Wp_statusbadfile = 1 ' Not a wave file!
Const Wp_statusbadwavformat = 2 ' Bad format (Bits|SampleRate|Other)
Const Wp_bufa = 0 ' Buffer A
Const Wp_bufb = 1 ' Buffer B
Const Wp_bufempty = 0 ' Buffer status Empty
Const Wp_buffull = 1 ' Buffer status Full
Dim Wp_btemp1 As Byte ' Needed for Fat Drivers
Dim Wp_filename As String * 14 ' Fat Filename
Dim Wp_buf As String * 4 ' misc. text
Dim Wp_buf_a(wp_bufsize) As Byte ' buffer A for double buffering
Dim Wp_buf_b(wp_bufsize) As Byte ' buffer B for double buffering
Dim Wp_a_buf_status As Byte ' buffer A full (1) or empty (0)
Dim Wp_b_buf_status As Byte ' buffer B full (1) or empty (0)
Dim Wp_activebuffer As Byte ' Actively playing buffer [0|1]
Dim Wp_bufpos As Byte ' Position in the active buffer
Dim Wp_status As Byte ' return status
Dim Wp_numchannels As Byte ' 1 or 2 channels
Dim Wp_bitspersample As Word ' 8 or 16 bits (only 8 at the moment)
Dim Wp_samplerate As Word ' Sample rate (EX: 8k|11K|22k|other)
Dim Wp_byterate As Word ' Read Bytes per second
Dim Wp_blockalign As Word '
Dim Wp_chunksize As Long '
Dim Wp_filesize As Long ' Size of wave file in bytes
' misc. vars
Dim Wp_ch As Byte '
Dim Wp_lx As Long '
Declare Sub Getwavefileinfo(wp_filename As String)
'Declare Sub Playwavefile(wp_filename As String)
Dim Btemp1 As Byte ' used by filesystem
Dim Filename As String * 12 ' Fat Filename
Dim Flag_error_sd As Byte
'=====[ Config misc stuff ]=====================================================
Config Serialout = Buffered , Size = 100 ' Serial Buffering
Config Serialin = Buffered , Size = 254
'-------------------------------------------------------------------------------
Enable Interrupts
Print
Print "SW V" ; Vsw
Print "Init. file system SD CARD... ";
Waitms 100
Flag_error_sd = 0
Btemp1 = Initfilesystem(1) ' Init Partition 1
If Btemp1 <> 0 Then
Print "Error: " ; Btemp1
Flag_error_sd = 1
Else
Print "OK"
End If
Filename = Dir( "*.wav")
On Compare1a Wp_play_isr ' set up interrupt vector
Print "Starting..."
Do
Do
If Filename <> "" Then
Getwavefileinfo Filename
Print
Print "Filename : " ; Filename
If Wp_status = Wp_statusbadfile Then
Print "Bad File!"
Goto Sound_error
End If
Open Filename For Binary As #10
''' Make sure its something we know how to play...
If Wp_numchannels <> 1 And Wp_numchannels <> 2 Then
Wp_status = Wp_statusbadwavformat
Print "Unknown format or Bad Format!"
Goto Sound_error
End If
If Wp_bitspersample <> 8 Then
Wp_status = Wp_statusbadwavformat
Print "Unknown format!"
Goto Sound_error
End If
Print "BitRate : " ; Wp_samplerate
Print "Channels : " ; Wp_numchannels
Print "BitsPerSecond : " ; Wp_bitspersample
Print "SampleRate : " ; Wp_samplerate
Print "BlockAlign : " ; Wp_blockalign
Print "ChunkSize : " ; Wp_chunksize
Print "FileSize : " ; Wp_filesize
'=====[ Config Timer2 for PWM audio output ]=================================
' This is done by using the PWM out puts on Timer2 (OC2A and OC2B)
Config Timer2 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Stop Timer2
'=====[ Setup Timer1 for sample pushing isr ]================================
' Timer1 is used for setting the rate for pushing the samples to timer2 (PWM)
Config Timer1 = Timer , Prescale = 1 , Compare A = Disconnect , Clear Timer = 1
Stop Timer1
'On Compare1a Wp_play_isr ' set up interrupt vector
''' setup compare1a reload value to match the SampleRate
Wp_lx = _xtal / Wp_samplerate ' CPU Speed / SampleRate of wave file
Compare1a = Wp_lx
Wp_lx = 45 : Seek #10 , Wp_lx ' seek to start of data at location 45
''' start loading buffers
Get #10 , Wp_buf_a(1) , , Wp_bufsize ' preload buffer A
Wp_a_buf_status = Wp_buffull ' mark buffer A as full
Get #10 , Wp_buf_b(1) , , Wp_bufsize ' preload buffer B
Wp_b_buf_status = Wp_buffull ' mark buffer B as full
Wp_activebuffer = Wp_bufa ' start with buf 0
Wp_bufpos = 0 ' Reset the buffer possition
'======[ start playing file!!! ]============================
Start Timer1 : Start Timer2
Enable Compare1a
''' Watch the two buffers and fill them up when ether is emty
While Eof(#10) = 0
If Wp_a_buf_status = Wp_bufempty Then
Get #10 , Wp_buf_a(1) , , Wp_bufsize
Wp_a_buf_status = Wp_buffull
Elseif Wp_b_buf_status = Wp_bufempty Then
Get #10 , Wp_buf_b(1) , , Wp_bufsize
Wp_b_buf_status = Wp_buffull
Else
' Both buffers are full here so this would be a good place to
' do some other stuff if needed. DON'T TAKE TOO LONG THOUGH! ;)
Wp_ch = Inkey()
If Wp_ch = " " Then
Wp_lx = Lof(#10) ' skip to end ...
Seek #10 , Wp_lx
End If
End If
Wend
Disable Compare1a
Stop Timer1 : Stop Timer2
Close #10
End If
Sound_error:
Filename = Dir() 'next wave
Waitms 500
Loop Until Filename = ""
Filename = Dir( "*.wav") 'torna al primo wave
Print : Print "End list"
Waitms 500
Loop
End 'end program
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sub Getwavefileinfo(wp_filename As String)
Wp_samplerate = 0 : Wp_numchannels = 0 : Wp_bitspersample = 0 ' clear old values
Wp_buf = ""
Open Wp_filename For Binary As #10
''' Read file format
Get #10 , Wp_buf , 9 , 4 ' should be "WAVE"
If Wp_buf <> "WAVE" Then
Close #10
Wp_status = Wp_statusbadfile
Return
End If
Get #10 , Wp_numchannels , 23 ' Read number of channels (1|2, Mono|Stereo)
Get #10 , Wp_samplerate , 25 ' Read Sample rate (EX: 8k|11K|22k|other)
Get #10 , Wp_byterate , 29 ' Read Bytes per second
Get #10 , Wp_bitspersample , 35 ' Read bits per sample (8|16)
Get #10 , Wp_blockalign , 33 ' BlockAlignment
Get #10 , Wp_chunksize , 41 ' ChunkSize
Wp_filesize = Lof(#10) ' Get file size
Close #10
End Sub
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'=====[ WP_Play ISR routine ]===================================================
' while Timer1 is active, cycle between buffer A and B and write its data
Wp_play_isr:
If Wp_activebuffer = Wp_bufa Then ' buffer A
Incr Wp_bufpos ' incrment to next byte
Pwm2a = Wp_buf_a(wp_bufpos) ' load sample into pwm2a
If Wp_numchannels = 2 Then Incr Wp_bufpos ' if stereo then...
Pwm2b = Wp_buf_a(wp_bufpos) ' load same sample if mono
If Wp_bufpos = Wp_bufsize Then ' hit end of buffer A
Wp_bufpos = 0 ' reset buffer pos to 0
Wp_activebuffer = Wp_bufb ' Set active buffer to B
Wp_a_buf_status = Wp_bufempty ' set buffer status empty
End If
Else ' buffer B
Incr Wp_bufpos ' incrment to next byte
Pwm2a = Wp_buf_b(wp_bufpos) ' load sample into pwm2a
If Wp_numchannels = 2 Then Incr Wp_bufpos ' if stereo then...
Pwm2b = Wp_buf_a(wp_bufpos) ' load same sample if mono
If Wp_bufpos = Wp_bufsize Then ' hit end of buffer A
Wp_bufpos = 0 ' reset buffer pos to 0
Wp_activebuffer = Wp_bufa ' Set active buffer to B
Wp_b_buf_status = Wp_bufempty ' set buffer status empty
End If
End If
Return