Page 1 of 1

Waveplayer stereo

PostPosted: 06 May 2016, 14:51
by tnnbascom
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.

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

Re: Waveplayer stereo

PostPosted: 10 May 2016, 08:22
by tnnbascom
ho risolto... questo è il codice corretto:

Code: Select all
'=====[ 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_B(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


un ultima domanda, perchè quando uso una sd card da 4gb formattata FAT32 mi restituisce l'errore 227: Error response Byte at Read Command ???

Con una SD card da 2gb tutto ok...