keilde FIR filtre yapmak ST32F4

Başlatan MühendisAdayAdayı, 30 Mayıs 2014, 15:14:32

MühendisAdayAdayı

Merhabalar,
Ben keilde FIR filtre yapmaya çalışıyorum.Öncelikle bu sitedeki wav uzantılı dosyayı çalma koduna baktım oradaki gibi wav.exe programını kullanarak wav uzantılı dosyayı C uzantılı hale getirip keilde include ediyorum.Sonra bu wav'ı FIR filtrenin içine çekiyorum filtreliyorum çıktılarıda bi diziye atıyorum.Bide DevC/C++ ta yapıyorum oradaki çıktılarla keildekini karşılaştırıyorum doğruysa led yaktırıyorum.
soracağım sorular;
1-Sonuçları atadığım dizinin tüm elemanlarını nasıl görebilirim.Tek tek karşılaştırma sıkıntı yapıyor .
2-Wav.exe nin çıktısı olan wav.c de bi dizi oluyor bu dizide 2642 tane eleman olmasına rağmen sizeof komutnu yazınca 2442 oluyor sorum şu wav.exe dosyasının içindeki dizinin ilk kaç elemanı o kaydın uzantısnı vs belirtiyor yani filtrelemeye kacıncı elemandan başlamam lazım.

Yardımlarınız için şimdiden teşekkürler...

MühendisAdayAdayı

Bilen kimse yok sanırım.
Vikipedi deki wav  anlatımında"WAV üç kısımdan oluşur. Bunlardan birincisi dosyayı WAV olarak adlandıran kısımdır. İkinci kısım değişkenlerin nitelendirildiği kısımdır. (örn: örnekleme frekansı). Uçüncü kısımdaysa asıl bilgi yani müzik parçası depolanır." diyor. Bendeki wav dosyasını wav.exe programına atınca bana C kodu veriyor ve char Wav[] adında bi dizinin içinde 2462 tane eleman oluyor bu elemanları kaçtanesi yukarıdaki açıklamaya göre bu dizinin uzantısını ve örnekleme frekansını belirtiyor acil yardım edermisiniz.
bide C de printf("%d",sizeof(Wav)); yazınca ekrana 2442 yazdırıyor.






z

#2
Bir zamanlar wav dosyasindan asil ses verilerini ceken bir kod yazmistim ama hic bir sey aklimda değil.

Internette wav file format diye aramis ve buldugum verilerle yola cikmistim.

https://www.picproje.org/index.php/topic,35896.msg267758.html#msg267758
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

pisayisi

Senin wav dosyalarını C de diziye çeviren program muhtemelen wav dosyasının formatı ile ilgili tanımlama bilgilerini üste atıyor. sizeof yazınca dizi boyutunda oluşan 20 fark muhtemelen bundan kaynaklanıyor. Ürettiğin C kodunu derleyicide açıp neden gözlemlemiyorsun diye sorucam?

Çıktın muhtemelen aşağıdakine benzer enformasyon bilgisi içeren bir dosya olacaktır...

y = /**********************************************************************
* Written by WAVToCode
* Date:             Mon Feb 28 07:47:30 PM
* FileName:         full8bitmono.C
* Interleaved:      Yes
* Signed:           No
* No. of channels:  1
* No. of samples:   253040
* Bits/Sample:      8
**********************************************************************/

#define NUM_ELEMENTS 253040

BYTE data[NUM_ELEMENTS] = {
127, 127, 128, 127, 127, 128, 128, 127, // 0-7
128, 127, 127, 127, 127, 127, 127, 127, // 8-15
...etc...


Diziyi elde ettikten sonra fır filtrelemeye tabi tutmak konusunda sıkıntı yaşamazsın std dsp library içinde hazır örnekler olması lazım...
Murat

MühendisAdayAdayı

FIR filtreyi kendim yazdım zaten C de çalışıyor orda sıkıntı yok gibi sıkıntı bi sitede okumuştum ilk 44 biti uzantı örnekleme vs diye geçiyordu orayı nasıl yapacağım dedim.Bide wav.c dosyasını keilde include edince normal C deki değerlerin aynısnımı işe sokuyor yoksa o dosya formatı fln onlarıda devreye katıyormu sonucları C den aldığım sonuclarla karşılaştırıyorum ilk 14 değerde hata yok ondan sonraki değerlerde led yanmıyor if in içinde float ta sıkıntı olmasın diye "==" ifadesinide kullanmıyorum.

pisayisi

wav.c dosyasını keilde dahil edince tabiki wav formatınla ilgili bilgileri biryerlerde tutacaktır. Aksi halde info bilgisi olmayan bir wav dizisinin değerlendirmesini yapma imkanı da olmaz. Matlab de wavread komutu var doğrudan Y=wavread()  yapınca Y dizisine info bilgisi olmadan datayı atıyor...
Murat

MühendisAdayAdayı

Tmm diyelimki wav a ait uzantı dosyalarını biyere kaydediyor. Bu wav.c dosyasında değerler şöyle char Wav[]={0x80,0x80,0x7F,0x7E,0x7E,0x7C,0x7B,0x7C,0x78,0x77,0x7D,0x83,0x8D,0x97,0x94,0x8E,0x8B,0x83,0x87,0x8F,..} ilk 20 değer bu şekilde.
bunları %d olarak yazdırıyorum [-128,-128 ,127,126,126,124,123,....] oluyor yalnız diziyi double Wav yapınca %f olarak yazdırıyorum bu sefer elemanlar [128.000000,128.000000,127.000000,126.000000,126.000000,124.000000,123.000000,124.000000,120.000000] oluyor bu ikinci hesaplattığım gibi matlabta filter fonksiyonunda hesaplatınca değerlerim C de hesaplanan ile aynı oluyor keilde karşılaştırırken il 14 değerde sorun yapmıyor 15. değerden sora sıkıntı veriyor isterseniz kodları paylaşayım bide siz deneyin.

kralsam

Selamlar,
Öncelikle karşılaştırma olayını nasıl yaptığını madde madde açıklığa kavuşturabilirmiyiz?

Keilde nasıl karşılaştırıyorsun yani?

MühendisAdayAdayı

Önceleri ;
if(Sonuc[7]== Dac1[7]){GPIOD->ODR=0x00008000;} bu şekilde yapıyordum floatlarla ilgili IEEE standartlarını öğrenince onu değiştirip

if(((Sonuc[7]+0.005) >= Dac1[7]) && ((Sonuc[7]-0.005) <= Dac1[7])){GPIOD->ODR=0x00008000;/*Delay_();*/} bu şekilde yapmaya başladım
ilk yazdığım şekilde yaparken 8. değerde hata veriyordu şimdi 15 te hata veriyor.

kralsam

Alıntı yapılan: MühendisAdayAdayı - 01 Haziran 2014, 10:42:34
Önceleri ;
if(Sonuc[7]== Dac1[7]){GPIOD->ODR=0x00008000;} bu şekilde yapıyordum floatlarla ilgili IEEE standartlarını öğrenince onu değiştirip

if(((Sonuc[7]+0.005) >= Dac1[7]) && ((Sonuc[7]-0.005) <= Dac1[7])){GPIOD->ODR=0x00008000;/*Delay_();*/} bu şekilde yapmaya başladım
ilk yazdığım şekilde yaparken 8. değerde hata veriyordu şimdi 15 te hata veriyor.
Yanılmıyorsam girişler float değil. Çıkışlarıda float olması çok gerekli olmaz o halde, floattan kurtarıp Epsilon 1 olarak bir denesen olurmu? Yada epsilon değeri biraz büyütmeyi denedinmi? belki daha fazla bir hata oranı oluşuyor olabilir. Sorun o gibi görünüyor.

MühendisAdayAdayı

Epilson muhabbetini bilmiyorum kardeş.Bi anlata bilirsen denerim bitirme projesi bu yapmam lazım.
Bak bu wav.exe "Wav dosyasının en başında 44 bytelik header ve hemen ardından sayısal ses bilgileri geliyor.
Wav.exe adını verdiğim program, headera bakıp sayısal ses verisinin sample frekansını, ses verilerinin uzunluğunu, sesin kaç bit olduğunu, sesin mono mu yoksa sterio mu oldugunu öğreniyor ve ardından binary formattaki verileri, C de kolayca kullanılabilsin diye array tanımı yapıp içine hex veriler olarak C syntexında ASCI karakterlerle yazıyor." böyle çalışıyormuş yani oluşturduğu char türündeki dizinin içinde hex veriler var ben bunların burada yazılı olduğu gibi 44 ten mi başlamam gerekiyor filtrelemeye yoksa bu program zaten onu dizinin içindeki değerlere yazmıyormu?
Yardımlarınız için teşekkür ederim.

kralsam

Alıntı yapılan: MühendisAdayAdayı - 01 Haziran 2014, 12:33:22
Epilson muhabbetini bilmiyorum kardeş.Bi anlata bilirsen denerim bitirme projesi bu yapmam lazım.
Bak bu wav.exe "Wav dosyasının en başında 44 bytelik header ve hemen ardından sayısal ses bilgileri geliyor.
Wav.exe adını verdiğim program, headera bakıp sayısal ses verisinin sample frekansını, ses verilerinin uzunluğunu, sesin kaç bit olduğunu, sesin mono mu yoksa sterio mu oldugunu öğreniyor ve ardından binary formattaki verileri, C de kolayca kullanılabilsin diye array tanımı yapıp içine hex veriler olarak C syntexında ASCI karakterlerle yazıyor." böyle çalışıyormuş yani oluşturduğu char türündeki dizinin içinde hex veriler var ben bunların burada yazılı olduğu gibi 44 ten mi başlamam gerekiyor filtrelemeye yoksa bu program zaten onu dizinin içindeki değerlere yazmıyormu?
Yardımlarınız için teşekkür ederim.

Öncelikle epsilonu bilmeme ihtimalin yok diye düşünüyorum ama hatırlamamış olabilirsin. Matematikteki + /- ε ifadesi yani. Senin uygulamadaki 0.005 değeri bir nevi ε değeridir. Yani o kadar hata payı olabilir anlamına gelir.

Bülent hocanın programı ise ben denediğimden hatırladığım kadarı ile o başlığı siliyordu. Yani dizideki sadece ses verisiydi. Fakat diğer değerleri biz bilindiği için timer ona göre kuruluyordu.(sample size orani falan)

Hatırladığım kadarıyla giriş datası 8 bit verilerde oluşan bir array. Öyle ise float değer zaten gerekli değil. Çıkış almak istesende DAC sana Float değer veremeyecek. Bence filtre işleminin bitişindeki çıkış dizisini char array tanımlayıp, çıkış dizisine yazarken float sayıları char a çevirip yazmalısın.
char out[ x ];
float tmp;
...
tmp=....;
..
out = (char)tmp;

gibi.

karşılaştırken hata oranı olarak 1 girmen yetecektir.

MühendisAdayAdayı

Tmm. Anladımda şu sıkıntı olabilir katsayıları Katsayıları MATLAB ta oluşturuyorum katsay.ı matrisi double olduğundan çıktıları char'a a çevirirsek filteleme hesap hatası olur tmm belki led yana bilir ama hesaplamada sonunda sıkıntı olur.

kralsam

#13
aslında bu çok büyük bir sorun oluşturmaz diye düşünüyorum. Ama dediğim gibi en sonda yapmalısın. Bu hata yanlış hatırlamıyorsam Kuantalama hatası benzeri bir hata. Yani zaten bu datayı bir ses kanalından çıkış vermek istesen doğru olsa bile veremeyeceksin. Ve giriş hassasiyetinde, aşağı yukarı o hata aralığında .

Aslında her sistemde bir hata vardır ama kabul edilebilir sınırlar içerisinde ise hatasız deriz. Numerik analiz dersi aldıysan oradan hatırlayabilirsin.
Kolay gelsin.

@Düzenleme: Aslında ARM daki çıktıyı UART ile PC de log tutup matlap çıktısı ile iki çıktının FFT sini matlab ile yada (freemat,octave) gibi bir programla çizdirerek hatayı gözlemleyebilirsin. Muhtemelen fark edilemeyecek düzeyde olacak.

MühendisAdayAdayı

Çıktıları UART modulu ile ekrana yazdırabilirmiyim UART modulunu hiç kullanmadım.