Riprodurre file WAV

Sezione dedicata al sistema di sviluppo BASCOM-AVR per i micro AVR
At90s, Attiny, Atmega e Xmega

Riprodurre file WAV

Postby atmegatnn » 05 Sep 2012, 11:04

Salve a tutti e complimenti per questa bella iniziativa di realizzare questo importante forum anche in italiano... ;)

Potreste indicarmi degli esempi su come riprodurre uno o + file WAV presenti su un PenDrive USB o MMC card usando il bascom e un atmega8(per esempio)...

La chicca sarebbe se mentre è in riproduzione un file, ne posso riprodurre un altro miscelandosi con quello in corso...

Grazie anticipatamente. :D
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby cyclone » 05 Sep 2012, 11:29

salve atmegann e benvenuto al forum :)

io penso che per riprodurre file-wav da sd-card hai necessità di gestire il file system FAT giusto?
mi sembra che dovresti implementare il dos per avr, ma meglio aspettare consiglio dal grande deluca che è l'amministatore e support del sito.

ciao ancora
User avatar
cyclone
 
Posts: 38
Joined: 27 Jan 2012, 11:49

Re: Riprodurre file WAV

Postby flz47655 » 05 Sep 2012, 11:33

Ciao e benvenuto!
Mi sa che con la miscela audio chiedi troppo ad un micro 8 bit/16Mhz..
Vediamo di riprodurre un file audio intanto (se è possibile), hai già un DAC con cui convertire il segnale audio in uscita per un altoparlante o usi un buzzer?
Last edited by flz47655 on 05 Sep 2012, 11:47, edited 1 time in total.
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: Riprodurre file WAV

Postby deluca » 05 Sep 2012, 11:43

@atmegann,

ben arrivato al fourm, se vuoi puoi presentarti nella sezione apposita.

relativamente al tuo topic il lettore è fattibilissimo in bascom usando una sd-card standard o la SDHC.
hai bisogno delle seguenti cose:

avr-dos
dac o rete resistiva dac
un micro con abbastanza memoria ram poichè avr-dos te ne magna un pò circa 2Kb.

il file wav che intendi riprodurre a quanti bit è registrato? e a che bitrate? è stereo o mono?

ciao e benvenuto
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: Riprodurre file WAV

Postby atmegatnn » 05 Sep 2012, 13:40

grazie a tutti del benvenuto e ancora complimenti....

per il formato e le caratteristiche del file wav non ci sono problemi lo adatterò in base all' hardware...(mono con qualità radio già va bene...)

:D
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby deluca » 05 Sep 2012, 14:45

partendo dal presupposto che sono l'autore di alcune semplici application notes di mcselec tra cui:
http://www.mcselec.com/index.php?option ... &Itemid=57

non mi è capitato finora di realizzare un wav player.
Questa sarebbe l'occasione buona per metterci al lavoro e realizzarlo.......

Altra domandina per iniziare con le specifiche progettuali e per stabilire i parametri del progetto:

il file audio deve essere necessariamente wav con head (44 byte) su cui sono descritti i parametri del file stesso e cioè:
RIFF" file description header
size of file
"WAVE" description header
"fmt " description header
size of WAVE section chunck
etc.....

oppure potrebbe essere un file audio di tipo raw senza header... ma in questo caso i file devono avere sempre lo stesso formato.
dico questo perchè da questa differenza si decide su come gestire lo stream dei dati audio.

per essere intanto certi di poter gestire lo stream partiamo da valori accettabili, allora fissiamo :
risoluzione: 8bit
freq sampler: 8Khz
tipo mono

ok?
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: Riprodurre file WAV

Postby atmegatnn » 05 Sep 2012, 15:02

Si, avevo visto l'applicazione AN #153 - MP3 Player... complimenti.
In quel caso si devono utilizzare file mp3... ma facendo una ricerca mi sembra un pò difficile reperire l'integrato VS1001k(o sbaglio??).... così ho optato per un lettore di Wav che richiede sicuramente meno hardware...

per il file wav se è possibile mantenerci sullo standard + diffuso....

sono ok i valori:

risoluzione: 8bit
freq sampler: 8Khz
tipo mono
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby deluca » 05 Sep 2012, 15:12

bene
ok per il lettore wav.

inizia e stendere qualche idea o codice descrivendo uno pseudo flow-chart.
noi siamo qui per aiutarti ...
anche perchè non possiamo scrivere l'intero programma ;)

ok?
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: Riprodurre file WAV

Postby flz47655 » 05 Sep 2012, 15:25

Ciao atmegatnn,
Hai già visto cosa c'è dentro un file wave? E' indispensabile capire come è strutturato, ho trovato un buon link con un esempio per capire i "byte del file": https://ccrma.stanford.edu/courses/422/ ... aveFormat/

Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: Riprodurre file WAV

Postby deluca » 05 Sep 2012, 20:57

@atmegann
scordati però di poter utilizzare un atmega8 per questo progetto

– 8Kbytes of In-System Self-programmable Flash program memory
– 512Bytes EEPROM
– 1Kbyte Internal SRAM

secondo i miei calcoli la flash e la ram sono insufficienti per implementare il filesystem.
inoltre volendo minimizzare i componenti esterni creando appositamente un dac con rete resistiva non avresti neppure una porta completa a 8 bit per generare un audio accettabile a meno della porta D ma così precluderesti l'uso della seriale. Potresti andare con un dac seriale o usare le uscite pwm per generare l'audio..... ma la cosa si complicherebbe molto a livello di codice e timing.

Ti consiglio di gestire il player con un micro un pò più performante almeno con 4K di ram e almeno un 40dip.
Io penserei ad un atmega644 o atmega1284 che va pure a 20Mhz e overclokkandolo arriviamo a 28Mhz (affidabili).

ciao
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: Riprodurre file WAV

Postby Micos » 05 Sep 2012, 21:27

eih eih aspettate un pò,
io sono alle prese con la realizzazione di un sintetizzatore musicale
viewtopic.php?f=9&t=310

ma l'idea di poter generare suoni wav memorizzati dalla sd-card mi alletta molto.
potrei mettere campioni di forme d'onda di strumenti diversi sulla sd-card e poi potrei caricarli in memoria per poterli suonare tipo tasiera a freq diverse.
mi si è accesa la lampadina. mi sa che stanotte non dormo.

pensate che questa mia idea sia fattibile? certo ... potrei potrei ma non è semplice lo so già
ciaoooooo
Micos
 
Posts: 36
Joined: 30 Jun 2011, 08:15
Location: Pisa

Re: Riprodurre file WAV

Postby atmegatnn » 21 Sep 2012, 10:25

Salve a tutti,

per motivi vari solo ora posso riprendere il questo discorso...
ho trovato questo link interessante:
http://elm-chan.org/works/sd20p/report.html

Il codice usato e in C

Code: Select all
/*----------------------------------------------------------------------------/
/  20-pin SD Sound Generator R0.01                                            /
/-----------------------------------------------------------------------------/
/ This project, program codes and circuit diagrams, is opened under license
/ policy of following trems.
/
/  Copyright (C) 2010, ChaN, all right reserved.
/
/ * This project is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/   personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.
/
/----------------------------------------------------------------------------*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include "pff.h"

#ifndef MODE
#error Wrong make file.
#endif

FUSES = {0xC1, 0xDD, 0xFF};   /* Fuse values: Low, High, Ext */
/* This is the fuse settings for this project. The fuse data will be output into the
   hex file with program code. However some flash programmers may not support this
   sort of hex files. If it is the case, use these values to program the fuse bits.
*/


#define FCC(c1,c2,c3,c4)   (((DWORD)c4<<24)+((DWORD)c3<<16)+((WORD)c2<<8)+(BYTE)c1)   /* FourCC */

#define LED_ON()   PORTB |= _BV(2)
#define LED_OFF()   PORTB &= ~_BV(2)

void delay_ms (WORD);   /* Defined in asmfunc.S */
void delay_us (WORD);   /* Defined in asmfunc.S */

EMPTY_INTERRUPT(PCINT_vect);


/*---------------------------------------------------------*/
/* Work Area                                               */
/*---------------------------------------------------------*/

volatile BYTE FifoRi, FifoWi, FifoCt;   /* FIFO controls */
BYTE Buff[256];      /* Audio output FIFO */

BYTE InMode, Cmd;   /* Input mode and received command value */

FATFS Fs;         /* File system object */
DIR Dir;         /* Directory object */
FILINFO Fno;      /* File information */

WORD rb;         /* Return value. Put this here to avoid avr-gcc's bug */



/*---------------------------------------------------------*/
/* Sub-routines                                            */
/*---------------------------------------------------------*/


static
void led_sign (
   BYTE ct      /* Number of flashes */
)
{
   do {
      delay_ms(200);
      LED_ON();
      delay_ms(100);
      LED_OFF();
   } while (--ct);
   delay_ms(1000);
}



static
BYTE chk_input (void)   /* 0:Not changed, 1:Changed */
{
   BYTE k, n;
   static BYTE pk, nk;


   wdt_reset();

   k = ~((PINA & 0xF8) | ((PINB >> 4) & 0x07));
   GIFR = _BV(PCIF);
   n = nk; nk = k;
   if (n != k || pk == k) return 0;

   pk = k; Cmd = k;

   return 1;
}



static
void ramp (      /* Ramp-up/down audio output (anti-pop feature) */
   int dir      /* 0:Ramp-down, 1:Ramp-up */
)
{
#if MODE != 0   /* This function is enebled on non-OCL output cfg. */
   BYTE v, d, n;


   if (dir) {
      v = 0; d = 1;
   } else {
      v = 128; d = 0xFF;
   }

   n = 128;
   do {
      v += d;
      OCR1A = v; OCR1B = v;
      delay_us(100);
   } while (--n);
#endif
}



static
void audio_on (void)   /* Enable audio output functions */
{
   if (!TCCR0B) {
      FifoCt = 0; FifoRi = 0; FifoWi = 0;      /* Reset audio FIFO */
      PLLCSR = 0b00000110;   /* Select PLL clock for TC1.ck */
      TCCR1A = 0b10100011;   /* Start TC1 with OC1A/OC1B PWM enabled */
      TCCR1B = 0b00000001;
      ramp(1);            /* Ramp-up to center level */
      TCCR0A = 0b00000001;   /* Enable TC0.ck = 2MHz as interval timer */
      TCCR0B = 0b00000010;
      TIMSK = _BV(OCIE0A);
   }
}



static
void audio_off (void)   /* Disable audio output functions */
{
   if (TCCR0B) {
      TCCR0B = 0;            /* Stop audio timer */
      ramp(0);            /* Ramp-down to GND level */
      TCCR1A = 0;   TCCR1B = 0;   /* Stop PWM */
   }
}



static
void wait_status (void)   /* Wait for a code change */
{
   BYTE n;


   if (Cmd) return;

   audio_off();   /* Disable audio output */

   for (;;) {
      n = 10;            /* Wait for a code change at active mode (100ms max) */
      do {
         delay_ms(10);
         chk_input();
      } while (--n && !Cmd);
      if (Cmd) break;      /* Return if any code change is detected within 100ms */

      cli();                     /* Enable pin change interrupt */
      GIMSK = _BV(PCIE1);
      WDTCR = _BV(WDE) | _BV(WDCE);   /* Disable WDT */
      WDTCR = 0;
      sleep_enable();               /* Wait for a code change at power-down mode */
      sei();
      sleep_cpu();
      sleep_disable();
      wdt_reset();               /* Enable WDT (1s) */
      WDTCR = _BV(WDE) | 0b110;
      GIMSK = 0;                  /* Disable pin change interrupt */
   }
}



static
DWORD load_header (void)   /* 2:I/O error, 4:Invalid file, >=1024:Ok(number of samples) */
{
   DWORD sz, f;
   BYTE b, al = 0;


   /* Check RIFF-WAVE file header */
   if (pf_read(Buff, 12, &rb)) return 2;
   if (rb != 12 || LD_DWORD(Buff+8) != FCC('W','A','V','E')) return 4;

   for (;;) {
      if (pf_read(Buff, 8, &rb)) return 2;      /* Get Chunk ID and size */
      if (rb != 8) return 4;
      sz = LD_DWORD(&Buff[4]);      /* Chunk size */

      switch (LD_DWORD(&Buff[0])) {   /* Switch by chunk type */
      case FCC('f','m','t',' ') :      /* 'fmt ' chunk */
         if (sz & 1) sz++;
         if (sz > 128 || sz < 16) return 4;      /* Check chunk size */
         if (pf_read(Buff, sz, &rb)) return 2;   /* Get the chunk content */
         if (rb != sz) return 4;
         if (Buff[0] != 1) return 4;            /* Check coding type (1: LPCM) */
         b = Buff[2];
         if (b < 1 && b > 2) return 4;          /* Check channels (1/2: Mono/Stereo) */
         GPIOR0 = al = b;                  /* Save channel flag */
         b = Buff[14];
         if (b != 8 && b != 16) return 4;      /* Check resolution (8/16 bit) */
         GPIOR0 |= b;                     /* Save resolution flag */
         if (b & 16) al <<= 1;
         f = LD_DWORD(&Buff[4]);               /* Check sampling freqency (8k-48k) */
         if (f < 8000 || f > 48000) return 4;
         OCR0A = (BYTE)(16000000UL/8/f) - 1;      /* Set interval timer (sampling period) */
         break;

      case FCC('d','a','t','a') :      /* 'data' chunk (start to play) */
         if (!al) return 4;                     /* Check if format valid */
         if (sz < 1024 || (sz & (al - 1))) return 4;   /* Check size */
         if (Fs.fptr & (al - 1)) return 4;         /* Check offset */
         return sz;

      case FCC('D','I','S','P') :      /* 'DISP' chunk (skip) */
      case FCC('f','a','c','t') :      /* 'fact' chunk (skip) */
      case FCC('L','I','S','T') :      /* 'LIST' chunk (skip) */
         if (sz & 1) sz++;
         if (pf_lseek(Fs.fptr + sz)) return 2;
         break;

      default :                  /* Unknown chunk */
         return 4;
      }
   }
}



static
BYTE play (      /* 0:Normal end, 1:Continue to play, 2:Disk error, 3:No file, 4:Invalid file */
   BYTE fn      /* File number (1..255) */
)
{
   DWORD sz, spa, sza;
   FRESULT res;
   WORD btr;
   BYTE n, i, rc;


   if (InMode >= 2) Cmd = 0;   /* Clear command code (Edge triggered) */

   /* Open an audio file "nnn.WAV" (nnn=001..255) */
   i = 2; n = fn;
   do {
      Buff[i] = (BYTE)(n % 10) + '0'; n /= 10;
   } while (i--);
   strcpy_P((char*)&Buff[3], PSTR(".WAV"));
   res = pf_open((char*)Buff);
   if (res == FR_NO_FILE) return 3;
   if (res != FR_OK) return 2;

   /* Get file parameters */
   sz = load_header();
   if (sz <= 4) return (BYTE)sz;   /* Invalid format */
   spa = Fs.fptr; sza = sz;      /* Save offset and size of audio data */

   LED_ON();
   audio_on();      /* Enable audio output */

   for (;;) {
      if (pf_read(0, 512 - (Fs.fptr % 512), &rb) != FR_OK) {      /* Snip sector unaligned part */
         rc = 2; break;
      }
      sz -= rb;
      do {
         /* Forward a bunch of the audio data to the FIFO */
         btr = (sz > 1024) ? 1024 : (WORD)sz;
         pf_read(0, btr, &rb);
         if (btr != rb) {
            rc = 2; break;
         }
         sz -= rb;

         /* Check input code change */
         rc = 0;
         if (chk_input()) {
            switch (InMode) {
            case 3:    /* Mode 3: Edge triggered (retriggerable) */
               if (Cmd) rc = 1;   /* Restart by a code change but zero */
               break;
            case 2:      /* Mode 2: Edge triggered */
               Cmd = 0;         /* Ignore code changes while playing */
               break;
            case 1:      /* Mode 1: Level triggered (sustained to end of the file) */
               if (Cmd && Cmd != fn) rc = 1;   /* Restart by a code change but zero */
               break;
            default:   /* Mode 0: Level triggered */
               if (Cmd != fn) rc = 1;   /* Restart by a code change */
            }
         }
      } while (!rc && rb == 1024);   /* Repeat until all data read or code change */

      if (rc || !Cmd || InMode >= 2) break;
      if (pf_lseek(spa) != FR_OK) {   /* Return top of audio data */
         rc = 3; break;
      }
      sz = sza;
   }

   while (FifoCt) ;         /* Wait for audio FIFO empty */
   OCR1A = 0x80; OCR1B = 0x80;   /* Return DAC out to center */

   LED_OFF();

   return rc;
}



/*-----------------------------------------------------------------------*/
/* Main                                                                  */

int main (void)
{
   BYTE rc;


   MCUSR = 0;                        /* Clear reset status */
   WDTCR = _BV(WDE) | 0b110;            /* Enable WDT (1s) */
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);   /* Select power down mode for sleep */
   PCMSK0 = 0b11111000;               /* Select pin change interrupt pins (SW1..SW8) */
   PCMSK1 = 0b01110000;

   /* Initialize ports */
   PORTA = 0b11111011;      /* PORTA [pppppLHp]*/
   DDRA  = 0b00000110;
   PORTB = 0b01110001;      /* PORTB [-pppLLLH] */
   DDRB  = 0b00001111;

   sei();

   for (;;) {
      if (pf_mount(&Fs) == FR_OK) {   /* Initialize FS */

         /* Load command input mode (if not exist, use mode 0 as default) */
         strcpy_P((char*)Buff, PSTR("000.TXT"));
         if (pf_open((char*)Buff) == FR_OK) {
            pf_read(&InMode, 1, &rb);
            InMode -= '0';
         }

         /* Main loop */
         do {
            wait_status();            /* Wait for any valid code */
            rc = play(Cmd);            /* Play corresponding audio file */
            if (rc >= 2) led_sign(rc);   /* Display if any error occured */
            if (rc != 1) Cmd = 0;      /* Clear code when normal end or error */
         } while (rc != 2);            /* Continue while no disk error */

         audio_off();   /* Disable audio output */
      }
      led_sign(2);   /* Disk error or Media mount failed */
   }
}



Visto che non ho mai usato il C, qualcuno gentilmente lo potrebbe riscrivere in BASCOM?

Grazie
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby atmegatnn » 21 Sep 2012, 11:24

Ferma ragazzi...
questo è quello che fa per me! ;)

http://mcselec.com/index2.php?option=co ... 906db5ea30
http://letsmakerobots.com/node/23622

Per piacere, dove trovo lo schema elettrico di come collegare la sd card al mio atmega?

Posso usare anche un atmega32?

Saluti
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby deluca » 21 Sep 2012, 13:34

non puoi usare atmega32 poichè
quel codice andrà bene per un micro con almeno 4Kb di ram (3281 byte usati) e con certe caratteristiche (atmega1280, atmega2560 ecc)
il codice compilato prende 9576 byte flash su un atmega2560, con ottimizzazione, nella versione 2.0.7.5

le connessioni con sd-card sfruttano i pin dedicati alla spi

'MMC Atmega
'1 MMC_CS PORTB.0
'2 MOSI PORTB.2
'3 GND
'4 +3.3V
'5 CLOCK PORTB.1
'6 GND
'7 MISO, PORTB.3

è un buon codice.... e mi sembra scritto bene.
prova ad usarlo e facci sapere.
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: Riprodurre file WAV

Postby atmegatnn » 21 Sep 2012, 13:51

Grazie gentilissimo,

per il discorso di come collegare al micro la sd??
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby atmegatnn » 21 Sep 2012, 15:25

scusami non avevo letto tutta la risposta.... :oops:
:D
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby atmegatnn » 25 Sep 2012, 11:48

Salve,

seguedo il codice di Glena http://mcselec.com/index2.php?option=co ... 906db5ea30
ho realizzato lo schema elettrico che ne pensate? I collegamenti della SD CARD e segnale audo sono OK?

[img=http://imageshack.us/a/img35/3937/unnamede.th.jpg]

Grazie
atmegatnn
 
Posts: 10
Joined: 05 Sep 2012, 10:56

Re: Riprodurre file WAV

Postby deluca » 26 Sep 2012, 10:41

a prima vista, (i pin della sd-card sono poco visibili), dovrebbe andare...

controlla l'uscita audio dal pwm OC,
avrai sicuramente bisogno di inserire un filtro passa basso per migliorare la qualità audio in uscita dal pwm.
ciao
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: Riprodurre file WAV

Postby flz47655 » 26 Sep 2012, 10:56

Ho visto lo schema e secondo me potresti avere problemi nell'inviare i comandi alla SD in quanto il micro lavora a 5v e alla SD potrebbe non piacergli questa tensione. Come soluzione veloce se non hai bitrare elevati un partitore di tensione dovrebbe bastare.
Ciao
flz47655
 
Posts: 639
Joined: 19 Jan 2012, 21:16

Re: Riprodurre file WAV

Postby deluca » 26 Sep 2012, 11:00

flz, hai proprio ragione.... mi era sfuggito.

@atmegatnn
è necessario che lavori tutto a 3.3Volt oppure devi interporre un adattatore di livello tra il micro e la sd-card.

PS. per evitarti l'adattatore ext, puoi alimentare il tuo Atmega1284P a 3.3volt, ma per essere certo del buon buon funzionamento, lo devi far andare ad un max di 10Mhz come da ds.

grazie flz.
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Next

Return to BASCOM-AVR

Who is online

Users browsing this forum: No registered users and 9 guests