Java ile GSM WAV Çözümleme

Java ile GSM WAV Çözümleme

A-law, μ-law ve PCM içeren WAV akışlarını Java ile 16 kHz PCM sözleşmesine dönüştüren codec zincirini açıklar. Kanal koruması, yeniden örnekleme, VAD/ASR sırası ve adli kullanım sınırları incelenir.

Telekomünikasyon kaynaklı bir WAV dosyasını işlemek, dosya uzantısını okuyup örnekleri doğrudan ses genliği kabul etmekten ibaret değildir. WAV bir kapsayıcıdır. İçinde doğrusal PCM bulunabileceği gibi A-law, μ-law veya başka bir codec ile kodlanmış ses de bulunabilir. Özellikle çağrı kayıtları, santral çıktıları ve eski telekomünikasyon sistemlerinden alınan dosyalarda kapsayıcı ile örnek kodlamasının birbirinden ayrılması gerekir.

Geliştirdiğim Java kütüphanesinin temel amacı bu ayrımı uygulama katmanından kaldırmaktı. Farklı codec gerçeklenimlerini ve yaygın dönüştürme kodlarını inceleyerek A-law, μ-law ve PCM yollarını tek bir akış modelinde birleştirdim. Kütüphaneyi yalnız dosya oynatmak için değil, VAD ve otomatik konuşma tanıma sistemlerine kararlı bir ses akışı sağlamak için kullandım. Girdi biçimi ne olursa olsun hedefte 16 kHz, 16 bit signed PCM ve ihtiyaca göre mono veya stereo bir akış elde ediliyor.

Bu yapı, adli bilişim çalışmalarında karşılaştığım farklı kayıt sistemlerinin seslerini ortak bir analiz düzlemine taşımamı sağladı. Bununla birlikte dönüştürülmüş sesin özgün delilin yerine geçmediğini, analiz için oluşturulmuş türev veri olduğunu her zaman ayrı değerlendirmek gerekir.

GSM WAV adlandırmasının sınırı

Kurumsal uygulamalarda 8 kHz telefon sesleri çoğu zaman genel olarak "GSM WAV" adıyla anılır. Bu kullanım operasyonel olarak anlaşılır olsa da teknik bakımdan kesin değildir. GSM Full Rate, G.711 A-law ve G.711 μ-law birbirinden farklı kodlama sistemleridir.

RTP profilinde GSM, PCMA ve PCMU ayrı codec tanımları olarak yer alır. PCMU için statik yük tipi 0, GSM için 3, PCMA için 8 kullanılır. PCMA ve PCMU, ITU-T G.711 kapsamında örnek başına sekiz bitlik logaritmik ölçeklenmiş ses kodlamalarıdır. GSM Full Rate ise ayrı bir çerçeve tabanlı konuşma codec'idir ve ETSI GSM 06.10, güncel adlandırmayla 3GPP TS 46.010 ailesinde tanımlanır.

WAV kapsayıcısı da yalnız PCM taşımaz. Microsoft'un WAVEFORMATEX tanımında PCM yanında A-law ve μ-law için ayrı format etiketleri bulunur. Dolayısıyla .wav uzantısı, içeriğin doğrusal PCM olduğunu tek başına göstermez. Dosyanın fmt bölümündeki kodlama türü, örnekleme hızı, kanal sayısı, frame boyutu ve bit derinliği birlikte incelenmelidir.

Paylaşılan kaynak kodun düşük seviyeli codec çekirdeği GSM 06.10 bit akışını çözmez. Akışın kodlaması A-law veya μ-law ise kendi G.711 dönüştürücüsünü kullanır. Diğer tanınan ses biçimlerini ise Java Sound dönüştürme katmanına bırakır. Sınıf adı uygulamanın çalıştığı telekomünikasyon alanını yansıtsa da teknik olarak gösterilen özel codec gerçeklenimi G.711 A-law ve μ-law çözümlemesidir.

Bu ayrım adli raporlarda özellikle önemlidir. Dosyanın bir GSM sisteminden elde edilmesi, içindeki sesin GSM Full Rate ile kodlandığını göstermez. Kaynak sistem, kapsayıcı ve codec ayrı ayrı tanımlanmalıdır.

PCM ve logaritmik sıkıştırma

Doğrusal PCM'de her örnek, belirli bir andaki işaret genliğini doğrusal sayısal ölçek üzerinde temsil eder. 16 bit signed PCM için örnekler yaklaşık olarak -32768 ile 32767 aralığındadır. Sıfıra yakın değerler sessizliği, büyük mutlak değerler daha yüksek genliği gösterir.

Telefon sesinde bütün bu aralığın aynı çözünürlükle kodlanması verimli değildir. Konuşmanın düşük genlikli bölümlerindeki küçük farklılıklar algısal olarak önem taşırken yüksek genlikli bölgelerde aynı mutlak nicemleme adımı daha az belirgindir. Companding yaklaşımı bu nedenle kodlamadan önce dinamik aralığı logaritmik olarak sıkıştırır, çözümleme sırasında yeniden genişletir.

G.711, ses frekanslarının PCM ile kodlanmasına ilişkin uzun geçmişe sahip bir telekomünikasyon standardıdır. Standart ailesinin 1972 tarihli sürümleri bulunmakta, yürürlükteki ana öneri ise 1988 sürümü ve sonraki ekler üzerinden sürdürülmektedir. ITU-T ayrıca G.711 için G.191 yazılım araçları içinde referans C kodu bulunduğunu belirtir.

A-law ve μ-law aynı amacı farklı segment ve nicemleme kurallarıyla gerçekleştirir. Her iki biçimde de bir örnek sekiz bitlik kod sözcüğüne dönüşür. Geleneksel 8 kHz telefon akışında bu, kanal başına saniyede 64.000 bit üretir. PCMA ve PCMU'nun RTP tanımı da sekiz bitlik örneklerin logaritmik ölçekleme sonrasında kullanıldığını belirtir.

Bu kodlamalar MP3 veya GSM Full Rate gibi zamansal çerçeveler arasında tahmin kuran codec'ler değildir. Her örnek bağımsız bir companding kodudur. Bu özellik çözümlemeyi son derece düşük maliyetli hale getirir. Bir byte değeri, 256 elemanlı tablodaki karşılığına bakılarak doğrusal PCM örneğine dönüştürülebilir.

Kütüphanemde A-law ve μ-law için 8 bit koddan 16 bit doğrusal değere giden lookup tabloları kullanılıyor. Her giriş örneği bir tablo erişimiyle çözülüyor ve sonuç istenen byte sırasına göre çıkış tamponuna yazılıyor. Aynı çekirdek signed veya unsigned 8 bit PCM üretimini ve A-law ile μ-law arasındaki doğrudan dönüşümü de destekliyor.

Toplam örnek sayısı \(S\) olduğunda temel çözümleme maliyeti:

\[
T(S)=\Theta(S)
\]

değerindedir. Her örnek bir kez okunur ve bir kez yazılır. Tablolar sabit boyutlu olduğundan ek algoritmik alan maliyeti:

\[
M(S)=\Theta(1)
\]

olarak değerlendirilebilir. Çıkış tamponu bu hesaba dahil değildir.

Akış tabanlı codec mimarisi

Kütüphanenin ana tasarım kararı, dönüşümü dosyanın tamamını belleğe alan bir fonksiyon olarak değil, AudioInputStream üzerinden çalışan bir codec zinciri olarak kurmaktı. FormatConversionProvider, Java Sound içinde giriş ve çıkış biçimleri arasında dönüşüm sağlayan codec ve transcoder katmanlarının temel arabirimidir. Kaynak biçimden hangi hedef biçimlerin üretilebildiğini bildirir ve dönüştürülmüş verinin okunacağı yeni bir ses akışı oluşturur.

Geliştirdiğim sağlayıcı 8 bit A-law ve μ-law kaynaklarını kabul eder. Hedefte signed veya unsigned 8 bit PCM ile big-endian ya da little-endian signed 16 bit PCM sunabilir. Örnekleme hızı, frame hızı ve kanal sayısı kaynak biçimden alınır. Böylece companding çözümü sırasında zaman ekseni veya kanal yapısı değiştirilmez.

Akışın read yolu frame sayısını hedef frame boyutuna göre hesaplar. Kaynaktan okunması gereken byte miktarı buna göre belirlenir. Çıkış örneği kaynak örneğinden daha büyük değilse aynı tampon üzerinde dönüşüm yapılabilir. Aksi halde yeniden kullanılabilen dahili tampon devreye girer. Her okumada yeni bir büyük dizi oluşturulmaz.

Bu yapı büyük kayıtlar için önemlidir. Birkaç saatlik çağrı kaydının tamamını belleğe almadan aşağıdaki zincir kurulabilir:

\[
\text{dosya akışı}
\rightarrow
\text{WAV ayrıştırma}
\rightarrow
\text{G.711 çözümleme}
\rightarrow
\text{yeniden örnekleme}
\rightarrow
\text{VAD veya ASR}
\]

Kaynak dosyanın önünde bir mebibaytlık tampon bulunur. Bu tercih, uzun ve ardışık okumada dosya sistemi çağrılarının sayısını azaltır. Dönüşüm katmanı da kendi çalışma tamponunu yalnız gerektiğinde büyütüp sonraki okumalarda yeniden kullanır.

Yüksek hacimli kullanımda tek byte okuyan read() yerine blok okuma yolu tercih edilmelidir. Tek byte yolu geçici bir byte dizisi oluştururken, toplu read(byte[], offset, length) yolu yeniden kullanılabilir kullanıcı tamponu üzerinde çalışır. Bu ayrım kısa bir dosyada önemsiz olsa da binlerce kayıt işleyen VAD ve ASR hatlarında allocation davranışını etkiler.

Çok kanallı örnek işleme

Ses kayıtlarında "çok kanallı" ifadesi yalnız stereo müzik anlamına gelmez. Çağrı sistemlerinde taraflar ayrı kanallarda, araç içi kayıtlarda kabin ve telsiz farklı kanallarda, mahkeme veya toplantı sistemlerinde ise birden fazla mikrofon bağımsız kanallarda bulunabilir. SWGDE, mono, stereo, dual mono ve bağımsız çok kanallı kayıtların adli inceleme ve iyileştirme sonuçlarını etkileyebileceğini özellikle belirtir.

Codec çekirdeğinde frame sayısı kanal sayısıyla çarpılarak gerçek örnek sayısına dönüştürülüyor. Dolayısıyla A-law ve μ-law çözümü yalnız ilk kanala uygulanmıyor; interleaved frame içindeki bütün kanallar işleniyor.

FloatSampleBuffer katmanı da kanalları ayrı kayan noktalı diziler halinde tutuyor. Interleaved byte verisi, frame boyutu kadar adımlarla ilerlenerek her kanal için bağımsız normalize edilmiş örneklere dönüştürülüyor. 8, 16, 24 ve 32 bit signed PCM, 8 bit unsigned PCM, big-endian ve little-endian gösterimler ayrı biçim türleri olarak ele alınıyor. 24 bit örneklerin üç veya dört byte içinde saklandığı düzenler de ayrıştırılıyor.

Yüksek seviyeli GsmWavDecoderStream ise çıkışı bilinçli olarak iki sözleşmeden birine indirger:

16 kHz, 16 bit, mono, little-endian PCM

16 kHz, 16 bit, stereo, little-endian PCM

Kaynak A-law veya μ-law ise önce kanal sayısı korunarak 16 bit PCM'e çözülür. Ardından mono seçeneğine ve kaynak kanal sayısına göre hedef mono veya stereo akış oluşturulur. Bu nedenle çekirdek çok kanallı girdiyi işler, ancak dışarıya keyfi sayıda kanal vermek yerine VAD ve ASR için bir veya iki kanallı standart çıktı sunar.

Bu ayrım benim kullanımımda yararlı oldu. Kanal bilgisinin önemli olduğu aşamada kaynak yapı korunabildi. Sonraki analiz hattında ise mono veya stereo olacağı önceden bilinen sabit bir PCM sözleşmesi kullanılabildi.

16 kHz hedefinin anlamı

8 kHz G.711 kaydını 16 kHz'e dönüştürmek, kayıtta bulunmayan yüksek frekans bilgisini geri getirmez. Nyquist sınırı nedeniyle 8 kHz örneklenmiş bir işaret en fazla 4 kHz'e kadar bilgi taşıyabilir. G.711 ile kullanılan klasik telefon bandı da yaklaşık 300 ile 3400 Hz arasındadır.

Bu nedenle 16 kHz'e yeniden örnekleme bir ses iyileştirme işlemi olarak görülmemelidir. Asıl işlevi, farklı kaynakları VAD ve ASR sistemlerinin beklediği ortak zaman ve örnek düzenine getirmektir.

16 kHz akışta:

\[
10\ \text{ms}=160\ \text{örnek}
\]

\[
20\ \text{ms}=320\ \text{örnek}
\]

\[
30\ \text{ms}=480\ \text{örnek}
\]

olur. Çerçeve tabanlı ses etkinliği algılama, özellik çıkarımı ve konuşma tanıma işlemlerinde bu sabit ilişki iş akışını sadeleştirir. Girişin 8, 11.025, 22.05 veya 44.1 kHz olması durumunda sonraki bileşenlerin her biri ayrı örnekleme hızı hesabı yapmak zorunda kalmaz.

Kod, bu son dönüşüm için Java Sound'un AudioSystem.getAudioInputStream(targetFormat, sourceStream) mekanizmasını kullanıyor. Java belgeleri, bu çağrının istenen hedef biçimi sağlayan bir format dönüştürücüsü varsa yeni akış döndürdüğünü, destek bulunmuyorsa IllegalArgumentException ürettiğini belirtir. Dolayısıyla G.711 çözümleyicisi kütüphanenin kendi kontrolündeyken, örnekleme hızı ve kanal dönüşümünün kullanılabilirliği çalışma ortamındaki Java Sound sağlayıcılarına bağlıdır.

Kurumsal dağıtımda bu nedenle yalnız geliştirme bilgisayarında başarılı açılan bir dosyaya güvenmedim. Kullanılan JDK dağıtımı ve hedef işletim sistemi üzerinde format dönüşüm matrisi doğrulanmalıdır. Kritik iş akışlarında bilinen giriş ve çıkış örnekleriyle otomatik test yapılması daha güvenlidir.

VAD ve ASR açısından doğru sıra

A-law veya μ-law byte'larını doğrudan signed PCM örnekleri gibi yorumlamak hatalıdır. Sekiz bitlik kod sözcükleri doğrusal genliği temsil etmez. Bit alanları işaret, segment ve nicemleme bilgisini taşır. Bu nedenle enerji, RMS, tepe değeri, sıfır geçişi veya spektral özellik hesaplamadan önce companding çözülmelidir.

Doğru işlem sırası şu şekildedir:

\[
\text{A-law veya μ-law}
\rightarrow
\text{doğrusal PCM}
\rightarrow
\text{kanal politikası}
\rightarrow
\text{yeniden örnekleme}
\rightarrow
\text{VAD}
\rightarrow
\text{ASR}
\]

Geliştirdiğim yapı bu sıralamayı stream zincirinin içine yerleştiriyor. Kullanıcı tarafına gelen byte'lar artık codec'e özgü telefon kodları değil, standart 16 bit PCM örnekleridir.

Kanal politikası VAD'den önce bilinçli seçilmelidir. İki kanalda farklı konuşmacılar bulunuyorsa doğrudan ortalama almak, aynı anda konuşma sırasında genlik iptali veya karışım oluşturabilir. Kanal bazlı VAD çalıştırmak, daha etkin kanalı seçmek veya iki kanalı ayrı ASR akışlarına vermek daha doğru olabilir. Mono seçeneği, bu karar verilmeden otomatik olarak etkinleştirilmemelidir.

Kütüphanenin mono ve stereo hedefleri ayrı tanımlaması bu açıdan yararlı bir temel oluşturur. Aynı çözümleme çekirdeği, tek kanallı ASR girişi veya kanal ayrımını koruyan stereo analiz yolu için kullanılabilir.

Adli bilişimde kullanım sınırı

Adli ses incelemesinde dönüştürülmüş PCM dosyası veya akışı özgün kayıt değildir. Özgün dosya kendi kapsayıcısı, codec'i, metadata'sı, zaman bilgileri ve hash değeriyle korunmalıdır. SWGDE, dijital özgünün bitstream kopyası üzerinden çalışma yapılmasını, özgün formatın ve metadata'nın korunmasını, kopyaların hash ile doğrulanmasını önerir.

Bu kütüphaneden elde edilen 16 kHz PCM akışı bir analiz kopyasıdır. VAD, konuşma tanıma, konuşmacı bölümleme, dinleme veya spektral analiz için kullanılabilir. Ancak aşağıdaki bilgiler ayrıca kayıt altına alınmalıdır:

Özgün dosyanın hash değeri

Özgün codec ve kapsayıcı

Özgün örnekleme hızı

Bit derinliği

Kanal sayısı ve kanal düzeni

Uygulanan A-law veya μ-law çözümü

Yeniden örnekleme yöntemi

Mono veya stereo dönüşüm kararı

Kullanılan yazılım ve sürümü

SWGDE de örnekleme hızı, bit derinliği, kanal sayısı, dosya biçimi, codec ve yapılan format dönüşümlerinin belgelenmesini ister. Gereksiz transcoding ve resampling işlemlerinin ses artefaktları oluşturabileceğini, dönüştürme gerektiğinde mümkünse sıkıştırılmamış PCM kullanılmasını ve anti-aliasing ayarlarının kaydedilmesini önerir.

A-law ve μ-law'dan PCM'e tablo tabanlı çözüm deterministik ve tekrarlanabilirdir. Aynı sekiz bitlik kod aynı PCM değerine dönüşür. Yeniden örnekleme ise filtre tasarımı, sınır davranışı ve sağlayıcı gerçeklenimine bağlıdır. Bu yüzden adli karşılaştırmada asıl kayıt korunmalı, yeniden örneklenmiş sürüm yalnız belirtilmiş analiz amacıyla kullanılmalıdır.

Kaynak kodun mühendislik sınırları

Kütüphanenin ana A-law ve μ-law'dan PCM'e çözüm yolu sade ve düşük maliyetlidir. Bununla birlikte genel amaçlı hale getirilecek bir sürümde bazı sınırlar açıkça yönetilmelidir.

İlk olarak, 16 kHz ve mono ya da stereo dönüşümü Java Sound sağlayıcısına bağlıdır. Dağıtım ortamı hedef dönüşümü sunmuyorsa işlem başarısız olur. Bağımsız ve bit düzeyinde aynı sonucu gerektiren sistemlerde yeniden örnekleyicinin de uygulama içine alınması gerekir.

İkinci olarak, gösterilen A-law ile μ-law arasındaki buffer-to-buffer dönüşüm yollarından birinde giriş ve çıkış offset rollerinin non-zero offset kullanımında ayrıca sınanması gerekir. Bu yol, GsmWavDecoderStream tarafından kullanılan A-law veya μ-law'dan PCM'e ana çözüm zincirinden ayrıdır. Yine de codec çekirdeği için farklı offset ve aynı tampon senaryolarını kapsayan testler gereklidir.

Üçüncü olarak, kayan noktalı buffer okuma yolunda oluşan IOException boş örnek dizisi gibi ele alınıyor. Kesintisiz ASR servisinde bu davranış akışı sonlandırmayı kolaylaştırabilir. Adli uygulamada ise gerçek EOF ile okuma hatasının ayrılması ve hatanın kayda geçirilmesi daha uygun olur.

Bunlar temel algoritmayı değiştiren sorunlar değildir. Kütüphanenin güçlü tarafı, codec çözümünü, kanal farkındalığını, frame hizasını, buffer yeniden kullanımını ve hedef PCM normalizasyonunu tek bir okunabilir akış sözleşmesinde birleştirmesidir.

Bu çalışmada asıl uzmanlık değeri yeni bir companding standardı icat etmekten gelmiyor. G.711, PCM, WAV kapsayıcısı, Java Sound dönüştürme modeli ve konuşma işleme gereksinimlerinin aynı veri hattında doğru sıraya yerleştirilmesinden geliyor.

Kurumsal ve adli bilişim çalışmalarımda elde ettiğim fayda da bu bütünlükten kaynaklandı. Telekomünikasyon kaynaklı farklı ses kayıtlarını önce doğru codec ile çözdüm, kanal yapısını kaybetmeden değerlendirdim ve VAD ile ASR bileşenlerine sabit 16 kHz PCM sözleşmesi sundum. Böylece dosya biçimi farklılıkları üst katman algoritmalarına taşınmadı ve ses işleme hattı daha öngörülebilir hale geldi.

Bu sayfanın QR kodu