2007年11月9日 星期五

IIS

昨天為了工作上的需要, 必須分析ADC的雜訊, 為了避免DAC的雜訊引響到ADC的測試結果, 我已用LA讀取IIS, 再用Python 寫了一個程式將IIS轉成文字檔, 以便交由execl匯入繪製圖形, 以下就是原始碼以及應用範例.


其實這個程式的結果也可以交給gnuplot之類了程式來做繪圖, 不過我手上沒有gnuplot, 就先用execl頂著用.
另外也可以加入FFT函數將時域轉換成頻率域, 即可做成類似頻譜分析的功能做訊分析, 或是失真分析, 這以後我會慢慢加上去.





#!python
# -*- coding: UTF-8 -*-
"""
此程式是用以分析自LA(孕龍科技之LA-161000)取得的IIS音訊資料, 其格式如下:
-020.971ms U U U
第一欄為取樣時間, 在取程式中棄之不用, 但請保留
第二欄為LRCK, 用以表示此時的SDOUT為左右聲道的資料
第三欄為BCLK, 為音訊資料的取樣時序
第四欄為SDOUT, 為音訊資料
目前此版程式僅支援標準IIS 24bit格式, 我將會依需要加入其他格式的支援
"""
import sys
import string
import math

__author__ = "Saber Lee, saberlee@gmail.com";
__date__ = "11/10/2007";
__revision__ = "0.1";

def __readData__( f):
OK= 1;
while 1:
line= f. readline();
if line == None: return None;
if len( line) == 0: return None;
toks= string. split( line, "\t");
for i in range( len( toks)):
toks[ i]= string. strip( toks[ i]);
if len( toks) <> 5: continue;
if (toks[ 1] == 'U') or (toks[ 2] == 'U') or (toks[ 3] == 'U'):
continue;
return toks[ 1:-1];

def IIS2Audio( iis, v= [ 0., 3.3], bit= 24):
audio= [];
wedig= (v[ 1] - v[ 0]) / math. pow( 2, bit-1);
for i in range( len( iis)):
d= [ 0., 0.];
d[ 0]= iis[ i][ 0] / wedig;
d[ 1]= iis[ i][ 1] / wedig;
audio. append( d);
return audio;

def ReadIIS( f):
LEFT= 1; # 定義常數
RIGHT= 0;

data= [ [], []]; # 預設變數
data[ 0]= __readData__( f);
Audio= []; # 音訊資料陣列

if data[ 0] == None: sys. exit( 0); # 如果不能取得正確的資料則結束程式
bit= 24; # 目前程式只支援24 bit IIS format.
channel= None;
Signal= None;

while 1: # 分析迴圈起點
data[ 1]= __readData__( f); # 讀取下一筆資料
if data[ 1] == None: break; # 若資料為無效資料則結束迴圈

if data[0][ 0] <> data[ 1][ 0]: # 比對LRCK是否為轉態
bit= 24;
if data[0][ 0] == '0' and data[ 1][ 0] == '1': # 比對LRCK 是否為 Rise Edge
channel= LEFT; # 此時的SDOUT為左聲道音訊
if Signal <> None: # 此行程式是為了避免第ㄧ筆為不完整的訊號資料
Audio. append( Signal);
Signal= [ 0.0, 0.0]; # 清除音訊資料
elif data[0][ 0] == '1' and data[ 1][ 0] == '0': # 比對LRCK 是否為 fulse Edge
if channel <> None: channel= RIGHT; # 此行程式是為了避免第ㄧ筆為不完整的訊號資料
else:
if channel == None: continue; # 此行程式是為了避免第ㄧ筆為不完整的訊號資料

if data[ 0][ 1] == '0' and data[ 1][ 1] == '1': # 比對BCLK 是否為 Rise Edge
# 在標準IIS的格式中LRCK轉態的下一各BCLK上的SDOUT是無效的資料, 故不予處理
if bit == 23: # 判斷正負號
if data[ 1][ 2] == '1':
s= -1;
else:
s= 1;
elif bit in range( 0, 22): # 讀取實數部的音訊資料
if s == 1:
if data[ 1][ 2] == '1': Signal[ channel]+= math. pow( 2, bit);
else:
if data[ 1][ 2] == '0': Signal[ channel]-= math. pow( 2, bit);
bit-= 1;
data[ 0]= data[ 1]; # 將現行BIT資料設為前一筆資料以便讀取下一筆音訊資料.

if Audio == []:
return None;
else:
return Audio;

def Help():
sys. stderr. write( "IIS.py Usage:\n");
sys. stderr. write( "\t IIS.py (iis textfile) (audio file)\n");
sys. stderr. write( "\t (iis textfile) is get from LA, and output by function export.\n");
sys. stderr. write( "\t (audio file) be be import by execl and use graph function to draw a wave drawing.\n");
sys. stderr. write( "\n\t%s\n" %( __author__));
sys. stderr. write( "\t%s\n" %( __date__));
sys. stderr. write( "\t%s\n" %( __revision__));

sys. exit();
if __name__ == '__main__':
if len( sys. argv) <> 3:
Help();

f= open( sys. argv[ 1], 'r'); # 開啟輸入資料檔
sys. stderr. write( "Processing IIS....\n");
Audio= ReadIIS( f);
f.close();

print len( Audio);
Audio1= IIS2Audio( Audio);
outf= open( sys. argv[ 2], 'w+');
for i in range( len( Audio)):
outf. write( "%10.0f\t%10.0f\n" %( Audio1[ i][ 0], Audio1[ i][ 1]));
sys. stderr. write( "%6.5f\t%6.5f\n" %( Audio1[ i][ 0], Audio1[ i][ 1]));
outf. close();