SD karttan
wav dosyası çalmak için uğraşıyorum haftalardır. Ses çıkış devremi önce pwm denedim. yapamadım. Sonra şekildeki devreyi tasarladım. Drençleri yaklaşık 2kat artacak şekilde takmaya çalışım devreye.
Yani 16F4685 in
D portunu komple
R2R merdiven devresi sayesinde
DAC a çevirmeye çalıştım.
(http://www.alicakil.com/resim/resimdepo/r2r.jpg)
Şimdi
wav dosyası formatı gereği dizinin tüm elemanları -1 ile 1 arasında float sayılardır. SD kartın registerleri ise 8 bitlik (0-255) alanlar olduğundan,
- ben tüm wav dosyasını önce 128 le çarparak genişlettim.
- ardından küsüratı atmak için her birini yuvarlattım..
- elimde kaldı -128+128 genliğine sahip tam sayı dizisi.
- sonra tüm diziyi 128 le topladım ki, ekseni öteledim. (offset y=0 dan y=128 ye gedi)
böylece tüm wav ses dizisi 0 ile 255 arasında değişen ses dizisi oldu.
İşte buyrun:
clc
y1=wavread('C:\ses.wav');
x = 1:1:(length(y1));
y1 = round(y1 * 128 + 128);
%wavplay(y1);
plot(x,y1);
yol = 'C:\ses.txt';
fid = fopen(yol,'w');
fprintf(fid, '%d-\n', y1);
fid = fopen(yol,'r');
fread(fid, 50, 'uint8=>char')
fclose(fid);
İşte Ses dizimin Son Hali:(http://i.hizliresim.com/wv5mGO.jpg) (http://hizliresim.com/wv5mGO)
SD karta yazmaya uygun hale gelen bu diziyi, SD karta yazdım. ve ses çalmaya çalıştım
Bu kadar adımı niye yaptım?-1+1 aralığındaki float sayılar için bu çözümlemeyi her seferinde PIC e yaptırmamak için. PIC için yükü demek olurdu.
Sonuç?
Ses kaydındaki ses çok zor anlaşılıyor. Bolca hışırtı var.
Saç baş yolmaya doğru adım adım....
varsa fikir öneri yardım,
Beklerim.
zamanlamaya dikkat etmemişsiniz. dac'a gönderdiğiniz her byte'ın eşit aralıkta ve doğru periyotda gittiğinden emin olmanız lazım bunun için timer kullanabilirsiniz.
gallavi hocam d portuna nasıl gönderdiğimi burda paylaşmadım. nasıl kanıya vardınız anlamadım ama şöyle gönderiyorum;
while(1) // (şart değişir. örnek olsun)
{
output_d(spi_read(0xFF)); // sd karttan d portuna ardışık ses byte larını yazıyorum.
delay_us(72);
}
zaman aralıkları eşit. SD kartta her 512 baytta bir gelen 2 CRC biti parazit yaptırır belki ama pek etkisi olmamalı. sanırım ses devrem sorunlu. görünmeyen hatarım var herhalde.
Ama en azından şunu teyit etmek isterim.
Devre Mantığım Doğru - sorunsuz değil mi? şemadaki.
mesaj birleştirme:: 28 Ocak 2014, 00:18:21
ADC den analog ses okuyup Dac tan sesi vermeye örnek gösterseniz ordan yola çıkar devam ederim. çünkü onu da yapamadım.
Şöyle bir sorun var ki PIC ın ADC sinde sesi örneklerken sesin negatif alternasını ne yapacağız?
PIC sadece pozitid tarafı okuyabilir. BU sorun nasıl aşılır?
Ben bir zamanlar wav çaldırmıştım. En önemli şey zamanında wav datalrını gönderebilmek. Delay ile olmaz. Sd kartan veri okurken süreyi ölç herzaman aynı zaman da oluyormu. Benim okduğumda 512 byten sonra büyük bir gecikme oluyordu.
O gecikmenin cızırtıya sebeb olduğunu görmüştüm. Dataları tampona tampondan kesme ile dac gönderince temiz ses gelmişti.
R2R devresi farklı geldi bana.
http://stor.altervista.org/firstbot/page9/page9.htm (http://stor.altervista.org/firstbot/page9/page9.htm)
Hep burdakiler gibi gördüm.
sadogan hocam R2R de sorun olduğunu sanmıyorum. oturup kirshoff akım gerilim yasası hesapları yaptım. 8 bit dataya göre doğru gerilim oluşuyor çıkışta. ama ucu açık devreyken hesapladım. mic yokken.
delaysiz- kesme olayını düşünmeye başladım. ama projede çok pürüz çıktı. altından kalkamayacağımı hissediyorum. ücreti karşılığı tasarımı yaptırsam diye düşünmeye başladım artık
Hocam wav dosyası verisinin float olduğu kanısına nasıl vardınız? WAV dosyası standartta stereo ise 2 x 16bit (sol sağ Int16 veya short tipi) veri bulundurur. Bu ham veriyi nasıl 128 ile çarpıyorsunuz? Eğer taşmasız çarpa yapmışsanız muhtemen çözünürlük bir bite inmiştir ve anlaşılması neredeyse imkansız olur. Eğer mono ise her sample iki baytlık olur. Tabi bu standart değerdir. İsterseniz 8-bitlik bir wav dosyası da oluşturabilirsiniz ancak mic kaydını doğrudan kullanıyorsanız muhtemelen mono 16-bittir. Bu durumda her sample için;
SAMPLE * 256 / 65535 (eğer işaretsiz tamsayı ile yapıyorsanız)
(SAMPLE * 128 / 32767) + 128 (eğer işaretli tamsayı ile yapıyorsanız)
WAV dosya başında genelde 58-baytlık header kısmı olur. Onu kaldırın. CRC verisi parazit yapacaktır bir tampon dizi oluşturarak iki ayrı threadda veri alma ve DAC'A basma yapın.
Ayrıca R2R DAC o şekilde yapılmaz. Doğrusal tepki vermesi için :
(http://upload.wikimedia.org/wikipedia/commons/7/7e/UnequalLadder.svg)
Veya logaritmik yeterli diyorsanız (ki mic kaydı için yeterlidir) :
(http://upload.wikimedia.org/wikipedia/commons/4/41/R2r-ladder.png)
a0 en düşük değerli bite gelecek şekilde bağlayın.
Niye yaptırıyorsun
RIFF-WAVE format sound files known as Microsoft wave file in LPCM, 8/16-bit, mono/stereo and upto 48kHz sampling rate
çalabilen elm chan ın attiny ile yaptığı var,
http://elm-chan.org/works/sd8p/report.html (http://elm-chan.org/works/sd8p/report.html)
18f için uyarlanmış hali http://projectproto.blogspot.com.tr/2010/05/pic18f-sd-wav-audio-player.html (http://projectproto.blogspot.com.tr/2010/05/pic18f-sd-wav-audio-player.html)
Alıntı yapılan: fatih6761 - 28 Ocak 2014, 01:47:40Hocam wav dosyası verisinin float olduğu kanısına nasıl vardınız? WAV dosyası standartta stereo ise 2 x 16bit (sol sağ Int16 veya short tipi) veri bulundurur. Bu ham veriyi nasıl 128 ile çarpıyorsunuz? Eğer taşmasız çarpa yapmışsanız muhtemen çözünürlük bir bite inmiştir ve anlaşılması neredeyse imkansız olur.
Hocam float olduğu kanısına nasıl mı vardım?
Matlabta wavread ile dosyayı okuyunca, inceledim ki tamamen -1 +1 aralığında küsüratlı, yani kayan noktalı, yani float sayılardan oluştuğunu gördüm. o halde bu matlabın komutuna özgü. 128 le çarptım çünkü (0-255) aralığına yayarak 8 bit tam sayı dizisi haline getirmeyi amaçladım.
65535 e bölmem kesinlikle hata olur. çünkü dediğim gibi matlab wav dosyasını her sample ı -1 +1 aralığında okuyor. her sample 16bitlik sayı olsaydı tamam eyvallah. hem wavın header kısmını zaten atlıyor matlab. dediğim gibi önce 8bitlik diziye çevirip öyle yazmıştım zaten. Hatta son halini matlabdan çaldırdım matlabda ses temiz çalıyor. Ama yazdığınız olayı mantık olarak anladım.
mesaj birleştirme:: 28 Ocak 2014, 16:11:03
CRC parazit yapması aklıma geldi ama önemsememiştim.
Alıntı yapılan: fatih6761 - 28 Ocak 2014, 01:47:40
bir tampon dizi oluşturarak iki ayrı threadda veri alma ve DAC'A basma yapın.
Bu kısmı kurgulayamadım kafamda. Bu kısmı biraz açabilr misin hocam?
mesaj birleştirme:: 28 Ocak 2014, 16:14:43
Alıntı yapılan: RaMu - 28 Ocak 2014, 01:49:52
18f için uyarlanmış hali http://projectproto.blogspot.com.tr/2010/05/pic18f-sd-wav-audio-player.html (http://projectproto.blogspot.com.tr/2010/05/pic18f-sd-wav-audio-player.html)
inceliyorum.
Edit: 18f source kodu indiremedim. ttnet 4shared i bloklamış.
Siz bu sayfaya girebiliyor musunuz?
http://www.4shared.com/file/3xcVM6rL/PIC18_SD_WAV_Audio_Player.html (http://www.4shared.com/file/3xcVM6rL/PIC18_SD_WAV_Audio_Player.html)
şunu buldum.
http://www.uchobby.com/index.php/2008/07/21/dspic-wav-player/ (http://www.uchobby.com/index.php/2008/07/21/dspic-wav-player/)
microchip lib olan mmd ile yapılmış. ama dspicler için. karmaşık geldi bana.
böyle başka örnek var mı?
opera int browser turbo modda giriyor,
proxy ilede girebilirsin.
DAC ın pek dac a benzemiyor. -1 +1 arası sayıları nasıl elde ettin bunu anlamadım öyle olmaması lazım (dosya 32 bitlik değilse). 8 bit işaretsiz veya 16 bit işaretli sayılar elde etmen lazım. ayrıca bunları yuvarlayıp 0-255 arasına çektiğinde de gürültü getiriyorsun ama asıl gürültü DAC dan geliyor bence onu düzeltmelisin. DAC çıkışına tampon bir kat koymalısın ayrıca DAC yükü de gürültü getirmesin.
çalarkende fs ye uygun çalmalısın. ayrıca uygun gördüğün düzeltmeyi yaptıktan sonra matlap da bir dene derim. ayrıca matlap de wav dosyasının header ınıda okumakta fayda var...
wav ın headrını ne yapayım ne gerek var? wavread bana istesem dosna mono mu stero mu? frekansı kaç? genliği kaç bit? hepsini döndürüyor. -1 +1 e çok takılmayın.
bakın çıktıtan örnek kestim:
-0.0611
-0.0444
-0.0413
-0.0786
-0.0739
-0.0665
-0.0687
-0.0464
-0.0627
-0.0427
-0.0042
-0.0090
-0.0222
-0.0658
-0.0535
-0.0537
0.0208
0.0031
y1 = y1*128; // 128 ile genişletme sonrası. (-128 + 128 aralığına genişletiliyor. kayıp mayıp yok)
-7.8164
-5.6797
-5.2813
-10.0625
-9.4531
-8.5078
-8.7930
-5.9336
-8.0313
-5.4648
-0.5313
-1.1523
-2.8438
-8.4180
-6.8477
-6.8789
2.6602
0.3984
y1 = y1 + 128; // -128 +128 den (0 , 255 e öteleme)
120.1836
122.3203
122.7188
117.9375
118.5469
119.4922
119.2070
122.0664
119.9688
122.5352
127.4688
126.8477
125.1563
119.5820
121.1523
121.1211
130.6602
128.3984
126.0430
122.0703
121.0586
123.6992
126.1758
123.8320
y1 = round(y1); // yuvarlama işlemi (kayıp sadece burada olur. çözürnülrük 1 bite düşmesi ne alakaysa. yok öyle birşey)
120
122
123
118
119
119
119
122
120
123
127
127
125
120
121
121
131
128
126
122
121
124
126
DAC devremi önerinize göre değiştirip test edicem ancak,DAC Devremde temel mantığın hala doğru olduğunu düşünüyorum. Mantık bununla aynı. Opamp olmaması sadece empadans uyumunu değiştitir hepsi bu.
örnek:(http://www.elektrik.gen.tr/sites/default/files/image/2008/01/dacadc/6.jpg)
örnek2:(http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/ietron/dac.gif)
Alıntı yapılan: OptimusPrime - 28 Ocak 2014, 03:27:05
DAC çıkışına tampon bir kat koymalısın
derken mesela örnekteki opamp katı gibi mi?
her neyse R2R yi unutalım. Şimdilik sadece sese odaklanıp, ADC den PC nin ses kartı çıkışını okuyup PWM den başka PC nin mikrofonu sürmeyi denedim. Başarılı oldu. Adım adım SD karta taşıyacağım şimdi.
Arkadaşlar ses bayağı düzeldi şu an. ama kulağı tırmalıyor. Sanırım frekans düşüklüğünden oda.
pwm i
setup_timer_2(T2_DIV_BY_1,255,1); // şeklinde PWM i en üst hızda sürüyorum. kristalim 8MHz. Daha nasıl hızlı sürerim onu düşünüyorum.frekansı hesalayamadm.
PWM çıkışını direk mi bağladınız mic. girişine?
mesaj birleştirme:: 28 Ocak 2014, 16:21:41
Şuradaki gibi bir filtre kullanın;
https://www.picproje.org/index.php/topic,35644.msg253593.html#msg253593 (https://www.picproje.org/index.php/topic,35644.msg253593.html#msg253593)
Alıntı yapılan: LukeSkywalker - 28 Ocak 2014, 16:19:23
PWM çıkışını direk mi bağladınız mic. girişine?
mesaj birleştirme:: 29 Ocak 2014, 06:21:41
Şuradaki gibi bir filtre kullanın;
https://www.picproje.org/index.php/topic,35644.msg253593.html#msg253593 (https://www.picproje.org/index.php/topic,35644.msg253593.html#msg253593)
Hocam direk bağlamadım. RC alçak geöiren filtre koydum zaten. seri 2.2k ardından paralel 100nF güzel ses alıyorum. yüksek dereceye gerek kalmadı bile.
Ama opamp koymadım.
Emin değilim ama Oradaki Opampın (gerilim takipçisi olan) amacı empedans uydurmak değil mi?
(Not: SD karttan henüz denemedim hala. şuan ADC-to- DAC çalışıyor)
Evet amaç empedans uygunlastirmak. Pwm frekansini en yukseğe ayarlayin.
setup_timer_2(T2_DIV_BY_1,255,1); 32MHz dahili işlemci frekansım.
Hesaplayınca
PWM Frekansım=31.25 kHz
frekansım en yüksekte. Ses çok iyi Hatta A.G.F sayesinde Baslı çıkıyor. Ses şiddetli noktalarda yetmezlik yapıyor. O da Genlik çözünürlüğündendir tahminim. (8bit) o kadarı önemsiz :)
keşke dijital bir scobum olsayıdı.. Ah fakirlik :)
(http://s29.postimg.cc/wkjugckd3/111.jpg)
aliciğim bak senin dac ı test ettim. gördüğün gibi devre lineer değil yanlış hesaplamışsın. lineer olamadığı gibi bazı değerlerde de saçmalıyor. ilk önce adam akıllı bir dac kullanman lazım. daha sonra da kafana göre dosyayı çalmaman lazım. örnekleme frekansı diye bir şey var. wav dosyasının header kısmında örnekleme frekansını matlab ile okuyup ona göre çalman lazım. pic in portuna aktarırkende gerçekten zamanlaman doğrumu görmen lazım. bunlar önemli şeyler. ondan sonra oraya buraya kondansatör ekleyip sesi düzeltmeye çalışma. düzelmez. pisa kulesi misali...
OptimusPrime
Olması gereken R-2R-4R-8R şekinde 2*n olarak gider. ama elimdeki dirençler bunlardıı o yüzden onları kullandım. O yüzden biraz bozuk çıkmış olabilir. Ben mantık olarak doğru yaptığımı hala düşünüyorum. Şöyle açıklayayım bakın:
(http://i.hizliresim.com/wz5dDR.png) (http://hizliresim.com/wz5dDR)
Demek istediğim budur. Bakın tamamen ardışık. Tamamen lineer.
Yani mantık doğru ama yine devresel başka bir hatam var. empedans uyumuna dikkat etmedim mesela. ve diğer söylediklerinize tamamen katılıyorum. çalışmamı elden geçiriyorum.
hocam bahsettiğiniz ilk önce tampona alma ondan sonra kesmeyle sürme işlemi nasıl olur biraz aydınlatabilir misiniz ?
Klasik yöntem Sd kart kullanıyorsan sd kartların okuma rutini byte byte görünsede 512 byte sayfa okuması söz konusu.Bu sayfa okuma sırasında cızırtıya sebeb olacak gecikme meydana gelir.Bu gecikme 512 byte bir gelir.Klasik olarak 2 adet 512byt den büyük dizi değişkeni tanımlıyorsun. TempA[512] TempB[512].. Ses dalgası örneklemesi diyelim 22khz. Timer0 veya başka timer i sn de 22khz kesme oluşturacak şekilde ayarlanır. Ana program içinde bir döngü içinde sd karttan dataları ilk önce TempA yı dolduruyorsun sonra TempB yi.TempB yi doldururken TempA daki dataları timer kesmesi ile dac göderiyorsun.TempA dolarken TempB deki dataları timer kesmesi ile dac gönderiyorsun.
Benim kullandığım yöntem bir tane temp oluşturuyorson. Örnek verecek olursam. Daire şeklinde pist olsun iki araba var. Birinci araba senkronizeli hareket ediyor.İkinci araba birinci takip ediyor ama asla birinci arabayı geçemez.Birinci araba senkronizeli dataları daca gönderen diğeri ise sd kartan temp i dataları dolduruyor. Kolay gelsin