Ako si pomocou audacity nechavas generovat tie cisla? jato skusam pomocou exportovat vyber ako… ale tam som nasiel najsurovejsie ulozenie zaznamu iba ako RAW…
Negeneroval jsem nějaká hudební data, bylo to protě jen pár čísel.
Tak som sa dostal až k tomu, že mi to nejaké zvuky vydáva, ale neni to to audio, ktore som prerabal…postpoval som nasledovne:
otvoril som si v audacity audio, ktore som orezal len na cca pol sekundy…
Tracks-> stereo track to mono
Tracks-> resample-> 11025Hz
Tracks-> render and mix
Súbor-> export -> vymazal som pomocou clear vsetky paramatre hlavicky -> OK-> format: other uncompressed flies -> options -> RAW(header-less), Unsigned 8bit PCM. -> uložiť.
Toto mi vytvorilo Raw súbor, ktorý som otvoril pomocou programu okteta.
V programe okteta po otvorení raw súboru som zvolil:
Súbor-> export -> C array…->data type: unsigned char-> a dal som si to ulozit ako C textovy dkument . Tuto deklaraciu som skopiroval do zdrojaku od Martina, ako:
unsigned char data[2008] PROGMEM = { --> zhluk 2009 vygenerovanych hodnot <–}
kompiloval som to s parametrami: POCET 1 a ZOSLABENIE 1
mam nastavit inaksiu frekvenciu pri resamplovani?
Jesli tam máš filtry podle toho pdfka, tak jsou nastavený na vzorkovačku 8 kHz. Tudíž ještě ubrat
Dál je potřeba abys sázel vzorky do pwm vzorkovací rychlostí, tedy každou 1/8000 vteřiny zapsat novej vzorek.
Unsigned 8bit PCM by mělo být vpořádku.
Těch hodnot bude 2008, při deklaraci to číslo v závorkách není index ale velikost pole.
pole[n] má “n” prvků, první prvek má index 0 a poslední “n-1”.
Ak definujes jednotlive hodnoty pola, staci zapisat
uint8_t pole] = PROGMEM = { --> zhluk vygenerovanych hodnot <--}
prekladac si spravy pocet doplni sam a vyhnes sa tak problemom s prepocitavanim poctu vzoriek.
Pokud by si chtěl přehrávat zvuk ve smyčce, tak už si ovšem délku pole někde udržovat musí.
Cele to mam v cykle while(1), takže sa mi to stále prehráva dokola…iba frekvencia ktoru pocujem z repracika je o dost nizsia, nez ta, ktoru pocujem, ked si to spustim ako slučku v PC…
A pouštíš to do pwm vzorkovací rychlostí?
To je predsa jasne. Okrem ineho i nato pani Ritchie a Kernighan do C-cka zaviedli “sizeof”
konkretne pouzitie
int pole] = {127,153,178,204,229,255,229,204,178,153,127,102,76,51,25,0,25,51,76,
102,127,153,178,204,229,255,229,204,178,153,127,102,76,51,25,0,25,51,
76,102};
int dlzka_pola;
int main(void)
{
while(1) {
//...
dlzka_pola = sizeof(pole);
//...
}
kto by inak ako jednoducho zistoval napriklad dlzku struktur ?
administrator: příspěvek byl upraven
Jenže sizeof vrací velikost v bytech. Pokud jde o pole, tak ji musíš na počet prvků přepočítat podle toho o jaký datový typ se jedná. Int má 2B(pokud nemáš nějak zařízenou jinou velikost), tedy “dlzka_pola = sizeof(pole)/sizeof(int);”.
Ještě, že jsi to připoměl, co nepíšu v C (bylo jen ve škole) na win a nepoužívám malloc se mi to nějak vykouřilo
Dik za doplnenie. Samozrejme, ze uplne spravne je ako uviedol Piityy. Ja som preto uviedol nazov premennej “dlzka_pola” v bajtoch, ale z mojho prispevku to vobec nemuselo byt jasne a tak i trochu zavadzajuce.
pocet_prvkov_pola = sizeof(pole)/sizeof(datovy_typ);
Inak pre 8b PWM je uplne zbytocne definovat pole ako int. Treba ho definovat ako uint8_t (8b unsigned definovany typ v GCC)
Diky, vyskusam to , avsak az o tyzden, v najblyzsom case ma cakaju 4 skusky:( urcite napisem ci sa to podarilo:)
Caute, tak som sa znovu vratil k mikropocitacu. Mam taku otazku. Skusal som navrhnut nastavenie pre phase and frequenci correct PWM, vyzera to nasledovne:
budem pouzivat 8 bit PWM. Kedže mám 8Mhz internal clock, počítať bude čítač UP od 0 do 255 a potom späť po nulu. Vyšlo mi že to bude 512 hodnôt tam aj späť. Keď vydelím 8Mhz/ 512 = 15,625 kHz frekvencia PWM. Registry mam nastavene takto:
TCCR1A:
COM1A1->1 , COM1A0->1 , COM1B1->0, COM1B0->0,FOC1A->0, FOC1B->0,
WGM11->0, WGM10->0
TCCR1B:
ICNC1->0 , ICES1->0, WGM13->1 , WGM12->0, CS12->0, CS11->0, CS10->1
ICR1 =499;
dúfam že sú moje úvahy správne.
Ešte mám jednu otázku. Keď do phase and frequenci correct PWM poslem nejaku hodnotu napr: 254, pocita to do 254, hodi na vystup 1, pocita dalej po 255, a po ceste dole to na hodnote 254 zase vypne -> z toho mi výde nejaký veľmi krátky impulz, nie? Potom teda 100 percentny impulz dosiahnem ked poslem do PWM 0?
Skoro
Phase and Frequency Correct PWM Mode:
“The counter counts repeatedly from BOTTOM(0x0000) to TOP and then from TOP to BOTTOM.”
COM1A1->1 , COM1A0->1 ==> “Set OC1A/OC1B on Compare Match when up-counting. Clear OC1A/OC1B on Compare Match when downcounting.”
WGM13=1 ==> “PWM, Phase and Frequency Correct, TOP=ICR1”
ICR1 =499;
Jelikož máš TOP v ICR1=499, bude jeden cyklus čítače trvat 1000 taktů (z 0 do TOP a zpět).
Se šířkou impulzu máš pravdu. Pokud to chceš obráceně (vyššímu číslu odpovídá delší jednička), nech COM1A0 v nule.
Tá včerajšia neskoršia hodina kedvy som to písal sa vyznamenala na tom co píšem:D ICR1 nastavujem na hodnotu 255
Ked zvolím Inverting mode, tak on nebude robit pulzy asi take, ze zacne s vystupom v 1, ked sa dopocita, skoci do nuly, a po ceste naspet zase zapne vystup na 1, tym to ten impulz rozdeli na dva, nie?
Autor dotazu nepíše nic o délce a kvalitě přehrávaného záznamu, ani o tom, jaký typ procesoru přesně by tu činnost měl vykonávat. Musí to být AVR? Nestačila by třeba tato věc (není to s AVR)? => dhservis.cz/download/negatron/wavplay/wavplay.html
PS: přiznávám se dobrovolně, že jsem vlákno nečetl, tak mě prosím nekamenujte, jestli už je vyřešeno…
Ten čítač jede pořád dokola, takže když začneš v 1, vypneš do 0, a zase zapneš, tak je to sice rozdělené, ale když se čítač otočí znovu, tak pokračuje v 1 a zas někde na compareMatch to shodí. Úrovně “1” z konce jednoho průchodu a začátku druhého se spojí do 1 impulzu .
Každopádně ikdyby ti ta pwm vyrobila dvojnásobnou frekvenci (což se tu nestane), tak ti to nevadí, filtry na výstupu se o to postarají(pokud jsme stále u toho zapojení z atmelácké appnote).
Ked som si to skúšal tak narýchlo nakresliť, a vlastne trochu aj prepočítať, tak z požadovaných šírok: 40 120 198 mi v inverting móde vyšli výstupné pulzy: 20 80 159 , to je dosť skreslené, nie?
aaaachajj, tak z tohoto ma klepne, tvarilo sa ze to ziadn prilohy nepriklada, a zrazu buuum, a je to tu prilozene milion krat. na tom obrazku som nacrtol 1. priebeh čítača 2. požadované pulzy, aké by som potreboval 3. výsledok z non inverting módu 4. výsledok z inverting módu. V prípade na obrázku som vychádzal z požadovaných hodnôt: 20% 60% 99%
Dnes som sa snažil napísať program ktorý by robil niečo také, že pri prerušení interupt1 tú trištvrte sekundu nahrá do pameti programu, a pri prerušení interrupt1 prehrá nahrané data. Zdroják vyzerá takto:
#include<avr/io.h>
#include<util/delay.h>
#include<avr/pgmspace.h>
#include <avr\interrupt.h>
#include <avr\signal.h>
#define POCET 1
unsigned char pole[7065] PROGMEM;
int temp;
int poc=0;
void prehraj()
{
for ( int i = 0; i < 7064; i++) {
for( int j = 0; j < POCET; j++) {
temp = pgm_read_byte(&(pole*));
OCR1A = temp;
while(!(TIFR & (1<<TOV1))) ;
// flag sa nuluje zapisom log.1 na jeho poziciu
TIFR |= (1<<TOV1);
}
}
}
SIGNAL(SIG_INTERRUPT0)
{
PORTC |= 0x32;
prehraj();
PORTC = 0x00;
}
SIGNAL(SIG_INTERRUPT1)
{
PORTC |= 0x32;
ADCSRA = (1<<ADSC);
poc = 0;
while(poc!=7064)
{
if(ADCSRA & (1<<ADIF))
{
temp = ADCH;
pole[poc] = temp;
ADCSRA = (1<<ADSC);
poc++;
}
else
{}
}
PORTC = 0x00;
}
int main()
{
DDRB |= 0x02; //pin B1 nastav?m ako v?stupn?
DDRC |= 0x20; //pin 5 portu C ako vystup, ostatne su vstupy
PORTC = 0x00;
sei(); // zapnem global prerušenia
MCUCR |= 0x0F; //ISC11 a ISC 10 >> 1 , ISC01 a ISC00 >>1
GICR |= 0xC0; //1<<INT1 1<<INT0
ADMUX = (0<<REFS1) |(0<<REFS0) | (1<<ADLAR) | (0<<MUX3)| (0<<MUX2)| (0<<MUX1)| (0<<MUX0);
ADCSRA = (1<<ADEN)|(0<<ADFR)|(0<<ADIE)|(0<<ADPS2)|(0<<ADPS1)|(0<<ADPS0);
// OC1A non-inverting mode
// OC1B nepripojen?
// foc1A aktivne FOC1B neaktivne
// fast PWM 8 bit
TCCR1A= (1<<COM1A1) | (1<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<FOC1A) | (0<<FOC1B) | (0<<WGM11) | (0<<WGM10);
// vypnute noise canceler a edge select
// fast PWM 8 bit
// fekvencia citaca pomer 1:1 s krystalom
TCCR1B= (0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
ICR1 = 255;
while(1)
{};
}
Avšak kompilátor mi hlási , že sa snažím zapisovať do read only pameti. Ked zapisy a citanie premennej pole zapoznamkujem, a spustím program tak po prijatí prerušenia na nahrávanie sa mi z prerušenia už nevráti. Mohli by ste mi prosim pomoct opravit moje chyby?*