roboforum.ru

Технический форум по робототехнике.

[Basic] WAV на FAT32 SD-card

Готовая электроника для самодельного робота. Уровень от начинающих до опытных конструкторов.

[Basic] WAV на FAT32 SD-card

Сообщение EdGull » 28 янв 2009, 00:18

Итак, пытаемся адаптировать код проигрывания WAV файлов с FAT32 SD-card из баскомовского аптонута AN#134
нужно обрезать код так чтобы можно было проиграть вавчик указанный в нашей переменной ну допустим "Wav_Out"
работа с директориями нафиг не нужна

для начала схемы:
WavePlayer.pdf
(53.55 КиБ) Скачиваний: 158

Minibot 2.06 draft.pdf
(111.83 КиБ) Скачиваний: 64


у них мега162 16МГц
у нас мега32 7.372800 MГц

у них звук выводится в
Ch1 PortE.2 (OC1B)
Ch2 PortB.4 (OC3B)
у нас PordD.7 (OC2)

еще меня смущает их кварц на 23КГц висящий на PortD.4 (TOSC1) и PortD.5 (TOSC2)
почему не часовой, можно обойтись без него?

основной код:
Код: Выделить всёРазвернуть
'***************************************************************
'Play a Wave file
'***************************************************************
'parses the wav file, sets up PWM on counter 1 and 3, generates 50X sample rate clock on counter 0, and plays wav file
'If playing a single wav, bugs out if not a compatible wav format
'If playing a dir, skips it, and gets the next.
'Flashes a message on the LCD if something is wrong.
Sub Playwav(direntry As Word)
Local Lcdtime As Byte , Attr As Byte
Attr = Dir_attr(direntry)       'get the attribute of the directory entry
Attr = Attr And Attr_directorymsk       'mask off all but the directory bit
Do
   If Playbutton = 0 Then
      Attr = 0
      Goto Playwavend       'don't like the song or dir, bug out
   End If
   If Attr = Attr_directorymsk Then
      'we are playing a whole dir
      Do
         Call Nextfile(direntry , 1)       'get next valid file
         If Direntry = 0 Then       'if next file returns zero then we have wraped
            Call Dir2lcd(direntry)       'display dir on lcd, for the last time
            Exit Sub       'and bug out
         End If
      Loop Until Dir_ext(direntry) = "WAV"       'find a WAV file
      Call Openfile(direntry)       'open the file
      Call Dir2lcd(direntry)       'display dir on lcd
   Else
      'we are playing one dir entry
      If Dir_ext(direntry) <> "WAV" Then       'make sure it is a WAV file
         Call Flashlcd(1 , 1 , "not a WAV")
         Exit Sub
      End If
   End If
   Fileoffset = 0       'finished playing with directories, set file offset to zero
   Gosub Parsewav       'check out the wav file and pull out format info
   If Warningcode > 0 Then       'If parsewav cannot find format info,
      Print "WAV error" ; Warningcode       'display warning on serial port for fun
      Call Flashlcd(1 , 1 , "WAV error")
      Goto Playwavend       'then bug out
   End If
   If Formattag <> 1 Then       'if Formattag is not 1 (uncompressed raw pcm)
      Call Flashlcd(1 , 1 , "Unsupported WAV")
      Goto Playwavend       'then bug out
   End If
   Endofdata = Endofdata + Fileoffset       'End of WAV data = current file offset + bytesperlong
   Endofdata = Endofdata + Bytesperlong
'Counter 1 & 3 are used as a PWM Digital to Analogue converter
   'Set up counter1 Timer Counter Control 1A & 1B
   'Compare Output Mode counter 1 B = clear on compare. Page 127
   Tccr1a = &B00100011
   'Waveform Generation Mode = 15, TOP = OCR1A, update of OCR1B at TOP, TOV1 flag on TOP. Page 129
   Tccr1b = &B00011001
   Samplespersec = _xtal / Samplespersec
   Decr Samplespersec
   Compare1a = Samplespersec       'Set TOP Counter1
   'Set up counter3 Timer Counter Control 3A & 3B
   'Compare Output Mode counter 3 B = clear on compare. Page 127
   Tccr3a = &B00100011
   'Waveform Generation Mode = 15, TOP = OCR3A, update of OCR3B at TOP, TOV3 flag on TOP. Page 129
   Tccr3b = &B00011001
   Compare3a = Samplespersec       'Set TOP Counter3
'Fudge factor is a multiply if we are doing 8 bit or divide if 16 bit.
'In 8 bit WAV uses more of the available range of the compare register.
'In 16 bit WAV makes sure the compare register is less than TOP by chopping off the LSBs.
   Fudgefactor = Samplespersec / &H00FF       'by default
   If Bitspersample = 16 Then Fudgefactor = &HFFFF / Samplespersec       'bad
   'If Bitspersample = 16 Then Fudgefactor = &H8FFF / Samplespersec       'better
   'If Bitspersample = 16 Then Fudgefactor = &H4FFF / Samplespersec       'best of bad bunch
   'If Bitspersample = 16 Then Fudgefactor = &H2FFF / Samplespersec       'clips peaks
'Counter 0 is used to generate a 50 X sample rate square wave (1:1 mark:space ratio) clock for switched cap filter.
   'set up counter0 Timer Counter Control 0
   'Clear Timer on Compare Match (CTC) Waveform Generation Mode 2. Page 99
   'Toggle OC0 on Compare Match. Page 100
   'clkI/O/(No prescaling). Page 101
   Tccr0 = &B00011001
   Incr Samplespersec
   Samplespersec = Samplespersec / 100       '50X and another 2X because we are using toggle on match
   Decr Samplespersec
   Ocr0 = Samplespersec
   Putpointer = 0       'Initialise fifo control
   Takepointer = 0
   Fifostatus = 0
   Counter1 = 0       'Sync counters, as they are running in parallel
   Counter3 = 0
   Gosub Fillfifo       'Give the fifo a head start
   'Set up interrupt on counter1
   in r16, timsk       'Read Timer Interrupt Mask
   ori r16, &B01000000       'Set OCIE1A: Timer/Counter1, Output Compare A Match Interrupt Enable
   !out timsk, r16       'Put it back.
   'Interrupt is a go
   'Lets play
   Lcdtime = Ticktock + 1       'time for lcd to display something
   Do
      Gosub Fillfifo
      If Lcdtime = Ticktock Then
         Locate 1 , 13       'play position
         Lcdtime = Ticktock + 1       'update lcd time
         If Ticktock.0 = 1 Then       'On even second
            Lcd "Play"
         Else       'On odd second
            Lcd "    "
         End If
      End If
      If Playbutton = 0 Then
         Attr = 0
         Goto Playwavend       'don't like the song or dir, bug out
      End If
   Loop Until Fileoffset >= Endofdata       'If we do not have any more data, then bug out
   'Finished Playing Wav File, but there are still a few bytes left in the fifo
   While Fifostatus <> 0
   'hang around
   Wend
   Playwavend:
   in r16, timsk       'Read Timer Interrupt Mask
   andi r16, &B10111111       'Clear OCIE1A: Timer/Counter1, Output Compare A Match Interrupt Enable
   !out timsk, r16       'Put it back
   'Interrupt is a NO go
   Tccr1a = 0       'Timer Counter Control 1A = off
   Tccr3a = 0       'Timer Counter Control 3A = off
   Tccr0 = 0       'Timer Counter Control 0 = off
   Locate 1 , 13
   Lcd "    "

   Gosub Flushbuffer
   Bitwait Playbutton , Set       'wait for finger to come off the play button
Loop Until Attr <> Attr_directorymsk       'loop if we are playing a dir
End Sub

Parsewav:
Warningcode = 1
Endofdata = Chunksize( "RIFF")       'Borrow End of Data, as it is not need yet
If Warningcode <> 0 Then Return

Warningcode = 2
Endofdata = Chunksize( "WAVE")       'Borrow End of Data, as it is not need yet
If Warningcode <> 0 Then Return

Warningcode = 3
Endofdata = Chunksize( "fmt " )       'Borrow End of Data, as it is not need yet
If Warningcode <> 0 Then Return

Loadadr Filebuffer(21) , X       'Source address
Loadadr Formattag , Z       'Destination address
ldi r21, bytesperword       'Number of bytes to xfer
!Call Mem2mem       'Transfer memory to memory

Loadadr Filebuffer(23) , X
Loadadr Numchannels , Z       'Destination address
ldi r21, bytesperword       'Number of bytes to xfer
!Call Mem2mem       'Transfer memory to memory

Loadadr Filebuffer(25) , X
Loadadr Samplespersec , Z       'Destination address
ldi r21, bytesperlong       'Number of bytes to xfer
!Call Mem2mem       'Transfer memory to memory

Loadadr Filebuffer(29) , X
Loadadr Avgbytespersec , Z       'Destination address
ldi r21, bytesperlong       'Number of bytes to xfer
!Call Mem2mem       'Transfer memory to memory
'Print "AvgBytesPerSec " ; Avgbytespersec

Loadadr Filebuffer(33) , X
Loadadr Blockalign , Z       'Destination address
ldi r21, bytesperword       'Number of bytes to xfer
!Call Mem2mem       'Transfer memory to memory
'Print "blkalg " ; Blockalign

Loadadr Filebuffer(35) , X
Loadadr Bitspersample , Z       'Destination address
ldi r21, bytesperlong       'Number of bytes to xfer
!Call Mem2mem       'Transfer memory to memory

Warningcode = 4
Endofdata = Chunksize( "data" )

Return


основные лаблы:
Код: Выделить всёРазвернуть
Fillfifo:
'written in ASM since this must be done as fast as possible.
'with 16000 samples per sec & 8 bits per channel & 2 channels, we have to move 32000 bytes per sec
'22.050ks/s & 16b/ch & 2 ch => 88kB/s which is about the limit.
'why fifo > 255 bytes? (= word pointers)
'It takes about 11ms (measured) to fill the 32k file buffer, so we must buffer at least 11ms worth of sound per channel.
'At 16ks/s = a buffer size of about 176. BUT if a fresh fat has to be loaded, it may take >30ms
'so a fifo > 500 is needed (= word pointers).
lds r16, {fifostatus}
cpi r16, &HFF
brne fillfifofill       'While fifo not full, fill it
ret       'RETURN is here
Fillfifofill:
rcall Getsample       'comes back with fudged ch word in r16-r17
push r16
push r17  'save just in case we have 2 channels
lds r18, {Numchannels}
cpi r18, 2       'if we have 2 channels
brne fillfifomono       'skip getting ch2 byte
rcall Getsample       'comes back with fudged ch word in r16-r17
Fillfifomono:
mov r20, r16
mov r21, r17       'copy Ch2 word, in either case
pop r17
pop r16   'pop Ch1 word in either case
lds r24, {putpointer}
lds r25, {putpointer+1}       'put pointer to r24-r25
adiw r24, 1       'incument put pointer
ldi r18, fifosize_lo
ldi r19, fifosize_hi
cp r18, r24
cpc r19, r25       'compare with fifo size
brne fillfifonowrap
clr r24
clr r25   'If we have reached end, then wrap
Fillfifonowrap:
lsl r24
rol r25   'multiply by bytes per word (2) since the fifo contains words
Loadadr Ch1fifo(1) , X
add r26, r24
adc r27, r25       'add pointer to fifo address
st X+, r16       'Store Ch1 lo
st X, r17 'Store Ch2 hi
Loadadr Ch2fifo(1) , X
add r26, r24
adc r27, r25       'add pointer to fifo address
st X+, r20       'Store Ch2 lo
st X, r21 'store Ch2 hi
'Check For Full
lsr r25
ror r24   'divide pointer by bytes per word (2)
sts {putpointer}, r24
sts {putpointer+1}, r25       'Store pointer
adiw r24, 1       'incument put pointer again
'Fifo size still in r18-r19
cp r18, r24
cpc r19, r25       'compare with fifo size again
brne fillfifonowrap1
clr r24
clr r25
Fillfifonowrap1:
lds r18,{takepointer}
lds r19, {takepointer+1}       'Take pointer to r16-r17
cp r24, r18
cpc r25, r19       'compare take pointer with put pointer
ldi r16, 1       'fifo not full
brne fillfifoend
ldi r16, &HFF       'fifo full indication
Fillfifoend:
sts {fifostatus}, r16
rjmp fillfifo


Код: Выделить всёРазвернуть
'***************************************************************
'New Sample Interrupt Service Routine
'***************************************************************
'Sticks a new sample into the Pulse Width Modulator compare registers, from fifos
'Updates take pointer and fifo status.
'This is called by interrupt, so all registers must stay un corrupted.
'With NoSave, must save used registers
Newsample:
push r16
in r16, sreg
push r16
push r17
push r18
push r24
push r25
push r26
push r27  'Save used registers
lds r24, {takepointer}
lds r25, {takepointer+1}       'get take pointer
lsl r24
rol r25   'multiply by bytes per word (2) since the fifo contains words
Loadadr Ch1fifo(1) , X
add r26, r24
adc r27, r25       'add takepointer to address
ld r16, X+       'get the pwm lo byte
ld r17, X 'get the pwm hi
!out ocr1bh, r17       'High register first for this 16 bit register, refer page 108
!out ocr1bl, r16       'Lo register next. The CH1fifo(takepointer) byte
Loadadr Ch2fifo(1) , X
add r26, r24
adc r27, r25       'add takepointer to address
ld r16, X+       'get the pwm lo byte
ld r17, X 'get the pwm hi
'Warning ocr3b outside "out" address range, use "sts" instead
sts Ocr3bh, r17       'High register first for this 16 bit register, refer page 108
sts Ocr3bl, r16       'Lo register next. The CH1fifo(takepointer) byte
lsr r25
ror r24   'divide pointer by bytes per word (2)
adiw r24, 1       'incrument takepointer
ldi r16, fifosize_lo
ldi r17, fifosize_hi
cp r24, r16
cpc r25, r17       'compare with fifosize
brne newsamplenowrap
clr r24   'if we have reached fifo size, set takepointer back to 0
clr r25
Newsamplenowrap:
lds r16, {putpointer}
lds r17, {putpointer+1}       'put pointer to r16-r17
cp r16 , r24
cpc r17, r25       'compare take pointer and put pointer
ldi r18, 0       'empty status and / or under run
breq newsamplenoupdateptr       'on next sample use the same PWM word if take pointer and put pointer are equal
ldi r18, 1       'not full status. We just took a byte, so it is not full.
sts {takepointer}, r24
sts {takepointer+1}, r25       'Save new takepointer if no under run
Newsamplenoupdateptr:
sts {fifostatus}, r18       'Update fifo status 0 = fifo empty, 1= not full
pop r27   'Restore used registers
pop r26
pop r25
pop r24
pop r18
pop r17
pop r16
!Out Sreg, r16
pop r16
reti


Добавлено спустя 3 часа 10 минут 2 секунды:
походу там ошибка в схеме.
в коде есть вот такая запись
'32.768kHz osc on TOSC1 and TOSC prescaled by 128 = 256Hz (1/256seconds). So Tcnt2 (8bit) will wrap every 1 second
'Config Timer2 = Timer , Async = On , Prescale = 1024 'Mass confusion here ???
Assr = &B00001000 'AS2: Asynchronous Timer/Counter2 ON
Tccr2 = &B00000101 'Mode 0 (normal), clkT2s/128
Вложения
AN#134.zip
(726.66 КиБ) Скачиваний: 58
Аватара пользователя
EdGull
 
Сообщения: 10211
Зарегистрирован: 28 дек 2004, 20:33
Откуда: Тольятти
Skype: Ed_Gull
прог. языки: Bascom AVR Basic
ФИО: Гуль Эдуард Викторович

Re: [Basic] WAV на FAT32 SD-card

Сообщение EdGull » 28 янв 2009, 09:22

кстати, к МиниБоту тоже можно подключючить часовой кварц это PortC.6 и PortC.7
они как раз не задействованы и переходные отверстия очень удачно расположены, как будто специально так сделали под часовик :D
Аватара пользователя
EdGull
 
Сообщения: 10211
Зарегистрирован: 28 дек 2004, 20:33
Откуда: Тольятти
Skype: Ed_Gull
прог. языки: Bascom AVR Basic
ФИО: Гуль Эдуард Викторович

Re: [Basic] WAV на FAT32 SD-card

Сообщение MiBBiM » 05 май 2009, 16:34

вот кстати страничка аппнота

Добавлено спустя 11 минут 3 секунды:
без усилителя хоть сколько-нибудь будет слышно?
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: [Basic] WAV на FAT32 SD-card

Сообщение EdGull » 05 май 2009, 16:36

что значит без усилителя?
ты динамик прям к ногам меги хочешь подпаять?
Аватара пользователя
EdGull
 
Сообщения: 10211
Зарегистрирован: 28 дек 2004, 20:33
Откуда: Тольятти
Skype: Ed_Gull
прог. языки: Bascom AVR Basic
ФИО: Гуль Эдуард Викторович

Re: [Basic] WAV на FAT32 SD-card

Сообщение MiBBiM » 05 май 2009, 16:59

вобщет да :D
тока вспоминая какой там ток через ножку, кажется мне что не гуд

Добавлено спустя 20 минут 35 секунд:
но все-таки? :wink:
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: [Basic] WAV на FAT32 SD-card

Сообщение galex1981 » 05 май 2009, 17:16

Ты хотя бы через ключевой транзистор подключи динамик, а то Мегу спалишь
if(!Operate) Read(pDatasheet);
Аватара пользователя
galex1981
 
Сообщения: 4363
Зарегистрирован: 04 дек 2008, 22:44
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович

Re: [Basic] WAV на FAT32 SD-card

Сообщение MiBBiM » 05 май 2009, 17:22

ок. биполярник мона?
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: [Basic] WAV на FAT32 SD-card

Сообщение galex1981 » 05 май 2009, 17:23

можно и биполярник и полевой...
if(!Operate) Read(pDatasheet);
Аватара пользователя
galex1981
 
Сообщения: 4363
Зарегистрирован: 04 дек 2008, 22:44
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович

Re: [Basic] WAV на FAT32 SD-card

Сообщение MiBBiM » 05 май 2009, 19:07

опа, кт315А :)

Добавлено спустя 40 минут 38 секунд:
как-то так?

Добавлено спустя 32 минуты 25 секунд:
не?

Добавлено спустя 15 минут 1 секунду:
эх была не была :)
Вложения
234.JPG
234.JPG (6.72 КиБ) Просмотров: 3859
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: [Basic] WAV на FAT32 SD-card

Сообщение ALHIMIK » 05 май 2009, 19:16

резистор на базу ?
Аватара пользователя
ALHIMIK
 
Сообщения: 997
Зарегистрирован: 05 окт 2008, 14:41
Откуда: СПб
прог. языки: C,Python

Re: [Basic] WAV на FAT32 SD-card

Сообщение MiBBiM » 05 май 2009, 19:45

без него работать не будет?
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: [Basic] WAV на FAT32 SD-card

Сообщение EdGull » 05 май 2009, 19:51

будет, но не долго.
Аватара пользователя
EdGull
 
Сообщения: 10211
Зарегистрирован: 28 дек 2004, 20:33
Откуда: Тольятти
Skype: Ed_Gull
прог. языки: Bascom AVR Basic
ФИО: Гуль Эдуард Викторович

Re: [Basic] WAV на FAT32 SD-card

Сообщение MiBBiM » 05 май 2009, 20:59

ндаа. вродь где-то слышал про усиление под 100 по току, ага
вобщем усилитель собрать не получилось. с горя повесил динамик на драйвер движков. надо посмотреть даташит, какую частоту макс они могут пропустить

Добавлено спустя 12 минут 35 секунд:
и ведь работает :Yahoo!: :Yahoo!:
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

Re: [Basic] WAV на FAT32 SD-card

Сообщение galex1981 » 05 май 2009, 21:28

Почему не получилось?
if(!Operate) Read(pDatasheet);
Аватара пользователя
galex1981
 
Сообщения: 4363
Зарегистрирован: 04 дек 2008, 22:44
Откуда: Камышин
Skype: galk-aleksandr1
прог. языки: Kotlin, Java, C, C++, Assm, BasCom, VB, php
ФИО: Галкин Александр Владимирович

Re: [Basic] WAV на FAT32 SD-card

Сообщение MiBBiM » 05 май 2009, 21:35

фик знает. какое-то слабенькое усиление получилось, почти не слышно (проверял (закороткой базы на +) через сопротивление, динамик потрескивал еле-еле)
Tomorrow will be. Better
Аватара пользователя
MiBBiM
 
Сообщения: 1866
Зарегистрирован: 29 окт 2007, 18:11
Откуда: Пермь
прог. языки: Brainfuck/Basic/Delphi/C++/Lisp/x86asm/JavaScript

След.

Вернуться в МиниБот — национальный класс роботов

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2