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