February 11, 2012

ID3v1 fazla basitmiş. ID3v2 ise her tür bilgiyi kapsıyor! Şarkıcının hangi noktada burnunu kaşıdığı filan bile oradadır. :)

Zafer, tabii öncelikle ID3v2 başlığı (3.1. ID3v2 header) ile başlamak gerekiyor. O başlık tanımında karışık gibi görünen bir 'size' bilgisini görüyorum. Dört bayttan oluşuyor ama her baytın üst biti 0 olmak zorundaymış. O yüzden de uzunluk 32 bit değil, 28 bitten oluşuyor. (Ama D'de 32 bitlik bir tür kullanmak zorundayız tabii.)

Bu kavram için de bir tür oluşturulabilir, işlev ismi daha uygun seçilebilir, vs. Ama sonuçta şöyle bir dönüşüm kullanmak gerekecek:

import std.exception;

uint uzunluk(ubyte[4] baytlar)
{
   uint sonuç = 0;

   foreach (bayt; baytlar) {
       enforce((bayt & 0x80) == 0, "Üst bit 1 olamaz");
       sonuç <<= 7;
       sonuç |= bayt;
   }

   return sonuç;
}

unittest
{
   assert(uzunluk([0x00, 0x00, 0x01, 0x00]) == 0x80);
   assert(uzunluk([0x7f, 0x7f, 0x7f, 0x7f]) == 0x0f_ff_ff_ff);
}

void main()
{}

Bit işlemlerine yabancı olan arkadaşlar için:

http://ddili.org/ders/d/bit_islemleri.html

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 13, 2012

Alıntı (acehreli:1328979346):

>

O başlık tanımında karışık gibi görünen bir 'size' bilgisini görüyorum. Dört bayttan oluşuyor ama her baytın üst biti 0 olmak zorundaymış. O yüzden de uzunluk 32 bit değil, 28 bitten oluşuyor. (Ama D'de 32 bitlik bir tür kullanmak zorundayız tabii.)

Ali doğrusunu söylemek gerekirse hiç bir şey anlamadım :-D Evet bu zor itirafı yaptıktan sonra gelelim bu koudaki sorulara.

size isimli bir alanımız var ve bu dört bayt yani 32 bitten oluşuyor. Bu durumda ben 32 bit ile 2_147_483_648 büyüklüğünde bir size değeri ifade edebilirim diye düşünürken bu dört baytı oluşturan her bir sekiz bitlik kümenin üst bitinin (en soldaki) sıfır olması gerektiği şeklinde bir kısıtlama ile karşılaşıyorum. Bu durumda benim 4 byte 32 bit olarak hayal ettiğim dünyam yine 4 byte ama her byteta kaybettiğim 1 bitten dolayı 28 bite düşmüş oluyor. Peki bu ne demek; bu demekki ben size değeri ile ancak 268_435_456 büyüklüğünde bir değeri ifade edebilirim.

Anladığım kadarıyla aslında bu bilgiyi yazarken karşımıza çıkacak bir sorun, okuma esnasında buradaki bitlerle zaten bir işimiz yok. Diğer taraftan üst bit işaret biti değil mi? Dolayısıyla zaten işaretli bir tip kullandığımızda o bit sıfır olmaz mı? Olmaz belkide ama anlamadığım için soruyorum. Şöyle birşeylerle uğraştım ama tabi bir çok noktada eksik bilgi olunca yaptığımında doğru mu yanlış mı olduğunu anlamadım. Bu arada header bilgisinide okumuş olduk sanırım :)

module main;

import std.stdio;
import std.exception;

struct ID3v2Header
{
	char tag[3];    // tag
	byte surum;     // version
	byte revizyon;  // minor
	byte bayrak;    // flags
	long boyut;     // size
}

void main()
{
   string dosyaYolu = "/home/zafer/DProje/SayiTest/Fading.mp3";

   File dosya = File(dosyaYolu, "r");

   ID3v2Header[1] paketler;
   dosya.rawRead(paketler);
   ID3v2Header paket = paketler[0];

   ubyte[4] buf = cast(ubyte)paket.boyut;

   writefln("Bayt : %x ", buf);
   writefln("Bayt : %b ", buf);
   writefln("Bayt : %s \n", uzunluk(buf));

   writeln("Tag : ", paket.tag);
   writeln("Version : ", paket.surum);
   writeln("Minor : ", paket.revizyon);
   writeln("Flags : ", paket.bayrak);
   writeln("Size : ", paket.boyut);
}

uint uzunluk(ubyte[4] baytlar)
{
   uint sonuç = 0;

   foreach (bayt; baytlar)
   {
       enforce((bayt & 0x80) == 0, "Üst bit 1 olamaz");

       sonuç = sonuç << 7;
       sonuç = sonuç | bayt;
   }

   return sonuç;
}
unittest
{
   assert(uzunluk([0x00, 0x00, 0x01, 0x00]) == 0x80);
   assert(uzunluk([0x7f, 0x7f, 0x7f, 0x7f]) == 0x0f_ff_ff_ff);
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 13, 2012

Alıntı (acehreli):

>

ID3v2 paketlerindeki bin bir bilginin hepsi şart değil ise bu mp3 dosyasının ne kadarının ID3v2 pakedi olduğunu herhalde bu uzunluktan anlarız.

Yani aslında ID3v1 çalışmalarımızda kullandığımız 128 değeri gibi bir işlevi var anladığım kadarıyla, gerçi bizde o değeri sabit kullanmak yerine yapının boyutundan faydalanarak elde ediyorduk ama sanırım ID3v2 için kullanılan alanın büyüklüğünü size değeri ile elde edeceğiz.

Benim anlam veremediğim (belki de sebebini bilmediğim için) neden böyle bir durum oluşmuş, yani neden size bilgisinden direk size değerini alamıyoruz da örnekte olduğu gibi uzunluk() gibi bir metod kullanmak zorunda kalıyoruz. Yoksa bu D'den kaynaklanan bir durum mu? Örneğin ben direk size diye okuduğum değeri neden kullanamıyorum ?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 13, 2012

Alıntı (zafer):

>

hiç bir şey anlamadım :-D

Onu söyledikten sonra da ne olduğunu doğru olarak anlatıyorsun. ;)

Alıntı:

>

Anladığım kadarıyla aslında bu bilgiyi yazarken karşımıza çıkacak bir sorun, okuma esnasında buradaki bitlerle zaten bir işimiz yok.

Bu bilgi tam da okuma sırasında gerekir. Bu gibi paketlerde başlık bölümündeki uzunluk bilgisi bütün pakedin uzunluğunu bildirir. ID3v2 paketlerindeki bin bir bilginin hepsi şart değil ise bu mp3 dosyasının ne kadarının ID3v2 pakedi olduğunu herhalde bu uzunluktan anlarız.

Alıntı:

>

Diğer taraftan üst bit işaret biti değil mi? Dolayısıyla zaten işaretli bir tip kullandığımızda o bit sıfır olmaz mı?

İşaretsiz türlerde o bit de değerin parçasıdır.

Ama burada baytları teker teker kendi başlarına değer olarak okumuyoruz. Dört bayt birden uzunluk bilgisini içerecek. Böyle bir bilgide de dört işaret biti olamazdı. Burada bize söylemek istedikleri, dört baytın arasında çıkartılıp atılması gereken dört bit var. O bitleri x ile gösterirsem, dört baytın ifade ettikleri gerçek değeri bitleri kaydırarak şöyle elde ediyoruz (her birisi bit):

'
asıl baytlar : xaaaaaaa xbbbbbbb xccccccc xddddddd
ifade ettikleri değer: 0000aaaa aaabbbbb bbcccccc cddddddd
'

Daha uygun ismini sonraya bıraktığım uzunluk() içindeki bit işlemleri dört bayttan o değeri elde ediyorlar.

Alıntı:

>

Bu arada header bilgisinide okumuş olduk sanırım :)

Uzunluğun tam ne anlama geldiğine göre başlıktan sonra ona bağlı olarak başka bilgiler de okumalıyız.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 13, 2012

Alıntı (zafer):

>

Yani aslında ID3v1 çalışmalarımızda kullandığımız 128 değeri gibi bir işlevi var

Aynen öyle. ID3v1'de sabit bir değerdi ID3v2'de ise her mp3'de farklı olabiliyor.

Alıntı:

>

gerçi bizde o değeri sabit kullanmak yerine yapının boyutundan faydalanarak elde ediyorduk

Doğru. Aslında biraz kırılgan bir tasarım çünkü bir programcı bir üyenin türünü değiştirse herşey bozulur. Programa onun doğruluğunu garantileyen şöyle bir satır eklemek yararlı olabilir:

static assert(ID3v1Pakedi.sizeof == 128);

Bir dereceye kadar koruma sağlar.

Alıntı:

>

ID3v2 için kullanılan alanın büyüklüğünü size değeri ile elde edeceğiz.

Evet. Protokollerde çok karşılaşılır. Örneğin IP paketlerinin (jargonuna daha uygun olarak "IP frame"lerinin) başlık bölümünün uzunluğu da öyle bir alanla bildirilir. Asıl verinin nerede başladığı o uzunluktan anlaşılır.

Alıntı:

>

Benim anlam veremediğim (belki de sebebini bilmediğim için) neden böyle bir durum oluşmuş, yani neden size bilgisinden direk size değerini alamıyoruz da örnekte olduğu gibi uzunluk() gibi bir metod kullanmak zorunda kalıyoruz.

Ben de emin değilim ama belgenin başlık bölümüyle ilgili bölümünde "to avoid the introducuction [sic] of 'false syncsignals'" diyorlar. Senkronizasyon sinyalleri eklememek içinmiş. (?) Bildiğim bir konu değil ama neyse ki bir anlamı varmış. :)

Alıntı:

>

Yoksa bu D'den kaynaklanan bir durum mu? Örneğin ben direk size diye okuduğum değeri neden kullanamıyorum ?

D ile ilgisi yok. ID3v2 standardı öyle olduğunu söylediği için. :) Biz de öyle okumak ve yazmak zorundayız:

Alıntı ("3.1. ID3v2 header"):

>

The ID3v2 tag size is encoded with four bytes where the most significant bit (bit 7) is set to zero in every byte, making a total of 28 bits. The zeroed bits are ignored, so a 257 bytes long tag is represented as $00 00 02 01.
The ID3v2 tag size is the size of the complete tag after unsychronisation, including padding, excluding the header but not excluding the extended header (total tag size - 10). Only 28 bits (representing up to 256MB) are used in the size description to avoid the introducuction of 'false syncsignals'.

Etiket uzunluğu, en üst bitleri 0 olan dört bayt ile ifade ediliyormuş. Örnek olarak 257'nin nasıl ifade edildiğini göstermişler. Şimdi o değerin pakede nasıl yazılacağını düşünelim. Belki bu açıdan bakınca daha da iyi anlaşılır.

257 değeri ikili sistemde şudur: '0b100000001' Onaltılı sistemde de '0x101'. Yani normalde dört bayt olarak '0x00 0x00 0x01 0x01' biçiminde görmeyi bekleriz. Gerçek bilgi odur. Programlama dilimizin bir değişkenindeki 257 uzunluk değeri şu düzendedir (bu örnekte hiç etkileri olmadığı için üstteki iki baytı noktayla gösteriyorum):

'........ ........ yyyyyyyy zzzzzzzz'

257 değerinde 'yyyyyyyy' ve 'zzzzzzzz''nin ikisi de 0x01. Şimdi her baytın en üst bitini gözardı edilecek olan bir 0 yapmamız gerekiyor. Öyle yapınca en sağdaki baytın en soldaki z'sine yer kalmaz. Onun için bir üst bayta kaydırılır (Bunu da protokol söylüyor ama üstü kapalı olarak). Aynı şey y'ler için de geçerli. Sonuçta bellekteki değişken yukarıdaki gibi iken, paket içine şöyle yazılması gerekiyor:

'........ ......yy 0yyyyyyz 0zzzzzzz'

257'nin asıl ifadesinde y'lere karşılık gelen bayt 0x01'di. Yani en sağdaki biti 1'di. z'de de öyleydi. Şimdi o bitleri yerlerine yerleştirelim:

'........ ......00 .0000010 .0000001'

O dört baytın değerleri de şudur: '0x00 0x00 0x02 0x01'

İşte başlık bölümünün belgesindeki 257 örneğinde onun için "a 257 bytes long tag is represented as $00 00 02 01" diyorlar.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 13, 2012

Genel olarak yüksek seviyeli dillerde ve ortamlarda çalıştığım için, bit ve byte kavramlarına oldukça uzağım. Ancak yinede detayları keşfetme arzumdan kaynaklanıyor olsa gerek bir o kadar da merak ediyor ve öğrenmek istiyorum.

Doğrusu mp3 bilgilerini okuma niyetiyle bu işlere girdiğimde işlerin bu noktaya geleceğini hiç düşünmemiştim ve bu güzel bilgileri okuduktan sonra bunları yaptığıma çok sevindim.

Diğer taraftan şu ID3v2 işini halen kavrayamadım. Aslında ID3 sitesindeki dokümanlar oldukça güzel ve açıklayıcı ancak benim yetersiz ingilizce bilgimle çok bir anlamı olmuyor :(

Genel olarak anladığım header bölümünden ID3v2 bilgi alanının sınırlarını tespit edip bu alan içindeki byte aralıklarını alıp frame denen yapılar içine doldurmak ve bu sayede bilgiyi elde etmek. Ancak bu framelere nasıl ulaşacağımızı hala anlamadım. Birde extended header bilgisi var tabi, karışık ama Ali'nin yardımları ile keyifli ve kesinlikle eğlenceli :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

February 15, 2012

Alıntı (zafer:1328953972):

>

Alıntı (Salih Dinçer):

>

Tabi, elimden geleni yaparım inşaallah. Yeter ki anlayabileceğim şeyler olsun...:)
Gerçi şu sıralar zorlu bir proje üzerine çalışıyorum. Birlikte paslaşır her ikisinin de üstesinden geliriz inşaallah...

Eğer yardımcı olabilirsem bende elimden geleni yapmak isterim tabi, bana yardımcı olabileceğin konu ise tabi ki frame denen yapıların hazırlanması, Ali'nin yazdıklaından da anladığıma göre bu frameler birer tapı şeklinde program içinde tamsil ediliyorlar. Şöyle bir liste var. (http://www.id3.org/id3v2.3.0#head-697d09c50ed7fa96fb66c6b0a9d93585e2652b0b)

Alıntı:

>

....
4.2.1 TALB [#TALB Album/Movie/Show title]
4.2.1 TBPM [#TBPM BPM (beats per minute)]
4.2.1 TCOM [#TCOM Composer]
4.2.1 TCON [#TCON Content type]
....

Bu yapıları oluşturma ve dosyadan okumada yardımcı olabilirsen çok sevinirim. Ben şöyle basit bir kod ile Frame ID değerini okumayı başardım ama bu aşamadan sonra Bu Id ile frameye basıl ulaşacağımı çözemedim. Tabi bu frame yapısınıda hazırlamak gerek sanırım.

> module main;
>
> import std.stdio;
>
> struct ID3v2Frame
> {
> 	char[4] frameId;
> 	char[4] size;
> 	char[2] flags;
> }
>
> void main()
> {
>     string dosyaYolu = "/home/zafer/DProje/SayiTest/Fading.mp3";
>
>     File dosya = File(dosyaYolu, "r");
>
>     dosya.seek(10, SEEK_SET);
>
>     ID3v2Frame[1] kutular;
>     dosya.rawRead(kutular);
>     ID3v2Frame kutu = kutular[0];
>
>     writefln("Frame ID: %s", kutu.frameId);
> }
> ```

>
> çıktısı :
> Alıntı:
> >
> > Frame ID: TALB
> >
>
Doğrusunu söylemek gerekirse ben de çok bir şey anlamadım...:)

Ama proje dosyalarını GitHub'dan inceliyorum ve aklıma bir şey gelirse katkı sağlayacağım inşaallah...

-- 
[ Bu gönderi, <http://ddili.org/forum>'dan dönüştürülmüştür. ]
1 2
Next ›   Last »