Ynt: stm32 microcontroller ve wav file

Başlatan Karamel, 15 Ağustos 2015, 01:49:39

Karamel

merhaba. wav player projeme baslaya bilmem icin yeterli bilgiye sahip olmadigim icin. adim adim. project in kisimlarini calisiyorum. ekran. microsd card. i2c vs vs adim adim. ilerledim.

simdi digital analog converter pinlerinden ses cikartmaya geldim.

bu baslikta 16 bit mono ve stereo olarak nasil caliyoruz. bunlari nasil yapiyoruz? bunu gorecegiz.

simdi hardware olarak stm32f103vet6 microcontroller kullandigimdan. wav file i 16 bit olarak okuyacagiz ama 12bit olarak digital analog converter dan cikartacagiz.

simdilik microsd card ile ilgili yeterli bilgim olmadigindan wav file i Z hocamin suradaki https://www.picproje.org/index.php/topic,35896.15.html kendi yaptigi converter software i kullandim. tam bu noktada hocama birsey sormak isterim. hocam siz example lari hep 8 bit uzerinden yapmissiniz. ben microcontrollerdan ses alabiliyorum ama yinede sormak istedim. programiniz 16 bit wav file i duzgunce hex code una cevirebiliyormu? (bir takim bana mantikli gelmeyen seyler oluyor. bunun icin bu soruyu sordum)

forumda her yeri okudum sayilir. 16 bit wav file ile ugrasan hoca olmamis gibi. simdi biz hem 16 bit file ile hasir nesir olacagiz. hemde bunu stereo olarak yapacagiz.

simdi hocamizin programi ile wav file i convert ettikten sonra. software bize wav.c seklinde bir file olusturuyor. bunun icersindede wav file imiz soyle char Wav[]={ basliyor.

biz once digital converter pinlerini acacagiz. daha sonra bir dongu icersinde. frequence hizimiz kadar file i output a update edecegiz.

oyleyse haydi baslayalim.
      unsigned long value;
      unsigned long conf1;
      unsigned long conf2;    

      value = 0;
      DAC1_Init(_DAC_CH1_ENABLE | _DAC_CH2_ENABLE);
      
      conf1 = _DAC_12_BIT | _DAC_TRIGGER_SW | _DAC_RIGHT_ALIGN;
      conf2 = _DAC_12_BIT | _DAC_TRIGGER_SW | _DAC_RIGHT_ALIGN;
      
      Delay_ms(100);


bu code lar ile digital analog converter in 1st channel ini ve 2nd channel ini active diyoruz. simdi 16 bit wav file hakkinda biraz bilgimiz olmasi gerekiyor. bu bilgilere buradan http://www.topherlee.com/software/pcm-tut-wavformat.html ulasiyoruz.

linten gordugumuz uzere ilk 44 byte file in description kismi. yani burada ismi. boyu vs hersey var. biz bunlari zaten bildigimizden bunlarla ilgilenmeyecegiz.

44. byte tan sonra ilk iki byte bi channel. sonraki 2 byte diger channel seklinde sonuna kadar gidiyor.

channel 1st                    channel 2nd
HByte     Low byte         HByte     Low byte   
45.         46.                    47.         48.   


simdi biz ilk bas kismi ile ilgilenmedigimizden ve on kisim cok kisa oldugundan bunlarida calacagiz. halbuki 44. byte tan baslasak iyi oldurdu ama simdilik boyle yapalim. wav file imizi 16 bit. 22050hz  stereo  olarak ayarliyoruz.

      while(1)
      {
          Ses_Cal = 0;                                         // Degiskenimizi temizledik
          Ses_Cal =  Wav[value];                       // wav file imizin ilk high byteini aldik.
          Ses_Cal = Ses_Cal << 8;                     // bunu 8 bit sola kaydirdik.
          
          Ses_Cal = Ses_Cal + Wav[value + 1]; // sola kaydirdigimiz 16 bitlik degiskenimize. wav file in low byte ini ekledik.
          
          Ses_Cal = Ses_Cal / 16;                      // simdi zurna burada dirt ediyor. dac unit in 12 bit oldugunu soylemistik. burada 16 bitlik veriyi. 12 bit e donustuyoruz.
          
          DAC1_Advanced_Ch1_Output(Ses_Cal, conf1);     // verimizi channel 1 e update ediyoruz ve aynilarini channel 2 icinde yapiyoruz. 
          
          Ses_Cal =  Wav[value + 2];
          Ses_Cal = Ses_Cal << 8;

          Ses_Cal = Ses_Cal + Wav[value + 3];

          Ses_Cal = Ses_Cal / 16;
          
          DAC1_Advanced_Ch2_Output(Ses_Cal, conf2);
          
          value++;  value++;  value++;  value++;                         

          Delay_us(85);
          if(value > 32256){value = 0; Delay_ms(3000);}  // wav file calininca counter degiskenimizi 0 yapip 3 sn bekliyoruz. sonra yine wav file imizi caliyoruz. 
      } 



code umuzun uzerine gerekli aciklamalari yaptim. neden 22050 hz frequence kullandik. 16 bit file da en iyi sonucu boyle aldim.

dac unit ten pc hoparlor input una soyle bir devre kullandim.



bu schematic i mikroe nin schematiclerinden arakladim  8) ama bu sanirim degerler bizim project imiz icin iyi degil ki. ses pc den cikas ses gibi degil.

sesi dduyup anlayabiliyorum ama boyle sarki dinlenecek sekilde degil. hafif hisirtilar var.



simdi sorularim soyle.

1- neden en iyi performance 22050 hz te cikti?
2- bu hisirtilarin problemi cikis a bagladigim devremi? bu devrem dogrumu? evet ise bunu neye gore sectik? yani mesela neden 3.3nf ta 10 nf degil? yada 10uf ta 1uf degil?

umarim bu yazdiklarimin. benim gibi yeni ogrenen kisilere faydasi dokunur...... ::)


mesaj birleştirme:: 15 Ağustos 2015, 02:06:41

bir baska sorumda. 1/22050 den bizim ornekleme frequence imiz yaklasik 45us olmaliyken neden iki katinda duzgun sonuc aldik?

Gökhan BEKEN

#1
16 bit DAC olacak ki 16 bitlik ses alasın. Hatırladığım kadarıyla stm32'lerde 12bit dac var(hepsinde aynı olmayabilir)
goldwave gibi bir program ile ses dosyasını aç, kaydederken 12 bitlik olarak kaydet. Sonra HxD hex programı ile dosyadaki bütün byte'ları kopyalayıp boşlukları " ,0x" olarak değiştir notepad++ ile. Bu verileri diziye at, programa öyle ver.

düzeltme: 12bit kayıt yapılmıyor
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

hocam ben zaten sesi 16 ya boylerek 12 bit elde ediyorum?  :-\

tekosis

gökhan hocam karamel programında 16  bitlik verinin ilk 4 bitini yok edip 12 bite çevirmiş. sesteki kalite kaybının nedenlerinden birisi bu olabilir. karamel ayrıca aşağıdaki şema ses kalitesini arttırabilir. şema mikromedia plus for stm32 arm devresinden kırpıntıdır :)


İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

Gökhan BEKEN

#4
12bit 22050hz'lik wav demek, saniyede 22050 adet 12bit eşit süre aralığıyla gidecek demek,
1sn=1000000us eder
saniyede 22050 adet 12bit demek, her 12 bit de bir  1000000/22050 =45,35147392290249 us bekleyeceksin demektir.

senin programda 85us bekleme var bunu neye göre yaptın? Sesi dinlerken yavaş çalması gerekir.
Bu arada byte sıralamasını 1byte kaydırırsan seste bozukluk olur.
Dediğim yöntemle sesi çevirip, dediğim süre kadar bekleme yaparak dener misin?
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

#5
Alıntı yapılan: tekosis - 15 Ağustos 2015, 02:25:22
gökhan hocam karamel programında 16  bitlik verinin ilk 4 bitini yok edip 12 bite çevirmiş. sesteki kalite kaybının nedenlerinden birisi bu olabilir. karamel ayrıca aşağıdaki şema ses kalitesini arttırabilir. şema mikromedia plus for stm32 arm devresinden kırpıntıdır :)



hocam bende zaten buradan kopya cektim ama bunlarin nasil calistigini anlamadan yaptim oldu seklinde calismak. ogretici olmuyor. bunun nasil olmasi gerektigine aciklayici bir cevap veren hoca ile bu schematic i test etmek lazim.  :-\

Alıntı yapılan: Gökhan BEKEN - 15 Ağustos 2015, 02:25:52
12bit 22050hz'lik wav demek, saniyede 22050 adet 12bit eşit süre aralığıyla gidecek demek,
1sn=1000000us eder
saniyede 22050 adet 12bit demek, her 12 bit de bir  1000000/45,35147392290249 us bekleyeceksin demektir.

senin programda 85us bekleme var bunu neye göre yaptın? Sesi dinlerken yavaş çalması gerekir.
Bu arada byte sıralamasını 1byte kaydırırsan seste bozukluk olur.
Dediğim yöntemle sesi çevirip, dediğim süre kadar bekleme yaparak dener misin?

hocam sanirim message imi iyi okumadiniz?

bende bunu dedim zaten. z hocamin programi suan bizi yaniltiyor olabilir. wav i tam olarak donusturmemis olabiliriz. ayrica su cikis kismindaki devre bizim devremize uygmuyor gibi hissediyorum.

ses cikiyor. bozuk degil. sadece belirli kisimlarinda hisirti cikiyor. tam hangi yerlerde sorun cikiyor? bunun deneyini nasil yapacagim bilmiyorum.

hesaplari bende yaptim hocam. yaklasik 45 us de bir systemi refresh yapmami gerekirken neden duzgun sonucu bunun 2 katinda aliyoruz? (45us de ses hizlandirilmis gibi oluyor)

mesaj birleştirme:: 15 Ağustos 2015, 02:43:25

Gokhan hocam. imkaniniz varsa 1-2 sn lik. 44100 khz yada 22050 khz frequance ta bir wav file i convert edip. ses hali ile hemde wav.c hali ile bir yere upload edebilirmisiniz?

su kisimdan goldwave gibi bir program ile ses dosyasını aç, kaydederken 12 bitlik olarak kaydet. Sonra HxD hex programı ile dosyadaki bütün byte'ları kopyalayıp boşlukları " ,0x" olarak değiştir notepad++ ile. Bu verileri diziye at, programa öyle ver. birsey anlamadigim icin bunu sizden istedim.

hocam birde mumkunse quality 16 bit olsun. ben bunu software olarak bolup 12 bit yapiyorum.

Gökhan BEKEN

Delay_us(85); fonksiyonun gerçekten 85us mi bekletiyor?
Bu fonsiyonu test etmelisin. Osiloskopun olsaydı iyi olurdu.

Şimdilik şöyle bir deneme yaparsan anlarız belki:
while(1){
Delay_us(1000000);
ledtoggle();
}

ama değer çok büyük olduğu için hata verebilir, eğer verirse şöyle yap
while(1){

   unsigned int i=1000;
   while(--i){
      Delay_us(1000);
   }

   ledtoggle();
}



Dosyayı birazdan atarım.
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

#7
hocam logic analyzerim ile test yapayim ama cikti degerinin kuculecegini sanmiyorum. bence 85 ten yuksek bir deger cikacak. cunku ortada code lar isleniyor. hemen deneyi yapayim.

mesaj birleştirme:: 15 Ağustos 2015, 02:58:06

hocam result 88.5 us iste. 45us nin yaklasik 2 kati. peki neden boyle?

mesaj birleştirme:: 15 Ağustos 2015, 03:09:14

bu arada teknosis hocanin isret ettigi kisimlari bread board a ekledim. ses daha kotu oldu. ilk hali daha iyiydi.

bu kisim sesin degisimine etki ediyor. burayi bilimsel olarak incelemek gerekli.

mesaj birleştirme:: 15 Ağustos 2015, 03:36:33

bir dakika!

z hocamizin programi sanirim beni kandiriyor. 8 bit mono 44100 hz de 66672 byte cikti veriyor. bunu 16 bit stereo 44100 hz yapiyorum. yine ayni byte ciktiyi veriyor ama dosyanin boyutu degisiyor. yani sorun convert isleminde olmali!

Gökhan BEKEN

#8
diziye attım:
http://www.gokhanbeken.com/dosyalar/sesdeneme123.txt

z hocanın programı ile oluşturduğun diziyi notepad++ ile açıp ",0x" leri sil, hex editöre yapıştır, bunu .raw olarak kaydet. Sonra goldwave ile aç, sana kaç bitlik ve kaç frekansta açmak istediğini felan soracak, gerekli ayarları yap,
dinlediğinde ses bozuk geliyorsa, hocanın çeviride sorun var diyebilirsin.



Ekleme:
Yukarıda verdiğim dosyayı bilgisayardan raw formatında(headersiz) dinlemek için bunu indir: http://gokhanbeken.com/dosyalar/ses_deneme_123-stereo.raw
goldwave programına import et, 22050hz, 16 bit, stereo  ve "little endian" seçili olsun.
Sonra play tuşuna bas dinle.

Eğer media player vs direkt dinlemek istersen dosyanın orjinali bu: http://gokhanbeken.com/dosyalar/ses_deneme_123-stereo.wav
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

#9
hocam verdiginiz linkten copy paste yapamiyorum. paste yapinca tek bir satira herseyi yazmaya calisiyor. compielr boyle satir olmaz diyor.

hocam sanirim bunu yazilim ile yaptiniz? sizden rica etsem. 8 yada 16 short sonunda bir enter ekleyebilirmisiniz? asagidaki gibi mesela.

,0x6301 ,0x6301 ,0x1A02 ,0x1A02 ,0x8C01 ,0x8C01 ,0x5800 ,0x5800 ,0xEAFF ,0xEAFF ,0x0201
,0x0201 ,0x0003 ,0x0003 ,0xA604 ,0xA604 ,0x2405 ,0x2405 ,0xA004 ,0xA004 ,0x0E04 ,0x0E04


mesaj birleştirme:: 15 Ağustos 2015, 04:06:40

hocam birde muzik ile deney yapsak daha belirgin olur. cunku bunu calinca hatayi anlamayabilirim. diyorum ya. anlasilacak kadar iyi caliyor. ama muzik dinleyebilecek kadar iyi degil.

Gökhan BEKEN

#10
Compiler öyle diyemez, dese dese IDE der, ben şimdiye kadar hiç bir IDE'de böyle bir sorunla karşılaşmadım.
Hangi IDE ve compiler'da deniyorsun?
Müzik ile yapmak için çok uzun bir buffer'a ihtiyaç var, bir c programı yazıp array'e çevirme işini onla yapmak lazım, hex editörü ile çevirmek zor oluyor kopyala yapıştır ile.
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

hocam mikroc for arm.

hocam bir satir a bu kadar cok letter yazamazsin diyor. yani butun array tek satir a yazilmaya calisiyor.

Gökhan BEKEN

Yine mikroc yine hata :D yıldık vallahi
neyse ben şimdi bir program hazırlıyorum, senin textini belirlediğin uzunluğa getirecek
Özel mesaj okumuyorum, lütfen göndermeyin.

Karamel

az once 8 bit lik ses dosyasinda birsey farkettim. 44100 hz 8 bit wav file da ses kalitesi daha tatmin edici. yalniz sunu farkettim. ses biterken. yani kisilirken. tam o esnada cizirti basliyor. digital analog converter cikisindaki resistor ve capacitor lu devreyi duzgun yapamadigim icin buna neden oluyor.

Gökhan BEKEN

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned int GetFileSize(FILE *dosya);

FILE *input;
FILE *output;



int main(int argc, char *argv[]) {
	
	unsigned int kacKarakterSonraEnterGelsin=16;
	printf("Kac karakter sonra enter gelsin..:");
	scanf("%d",&kacKarakterSonraEnterGelsin);
	
	
	printf("\r\n");
	
	
	input=fopen("input.txt", "rw+");
	if(NULL == input)
    {
        printf("input.txt bulunamadi!!!\n");
        return 1;
    }
    
	
	output=fopen("output.txt", "w+");
	if(NULL == output)
    {
        printf("output.txt bulunamadi!!!\n");
        return 1;
    }	
	
	unsigned int dosyaBoyutu=GetFileSize(input);
	printf("input dosyasi: %d byte",dosyaBoyutu);
	
	unsigned int i=0;
	while(i<dosyaBoyutu){
		unsigned char buffer[500];
		fread(buffer,1,kacKarakterSonraEnterGelsin,input);
		
		fwrite(buffer,1,kacKarakterSonraEnterGelsin,output);
		fprintf(output,"\r\n");
		
		i+=kacKarakterSonraEnterGelsin;
	}
	
	
	
	
	printf("islem tamamlanmistir\r\n");
	printf("Her %d karakterde bir satir basi yapilmistir.",kacKarakterSonraEnterGelsin);
	
	
	
	
	
	fclose(input);
	fclose(output);
	
	char bekle=0;
	scanf("%c",&bekle);
			
  	return 0;
}

unsigned int GetFileSize(FILE *dosya){
	unsigned int dosyaBoyutu=0, kaldigiYer=0;
	kaldigiYer=ftell(dosya);
	fseek(dosya, 0L, SEEK_END);
	dosyaBoyutu=ftell(dosya);
	fseek(dosya,kaldigiYer, SEEK_SET);
	return dosyaBoyutu;
}
Özel mesaj okumuyorum, lütfen göndermeyin.