這邊主要是將原wav過濾頻率, 只保留部分的音頻...
相信在google上也有很多的實作~
不過有找到一個方便的lib...
只要一個jar, 下個cmd就OK了~
使用dsp-collection.jar
出處:
http://www.source-code.biz/dsp/java/
用法很簡單~ 只要下cmd就好了
雖然偶不懂用那個演算法比較好XD..個人指導最高原則就是...能動就好了
ex:
java -cp dsp-collection.jar WavFilterFisher sample.wav bandpass chebyshev 4 -0.5 1000 5000 out.wav
來個檔案做圖解~ 雖然沒辦法濾得很乾淨, 但是看起來還是有差的+_+
原始檔頻譜
過濾後頻譜
2013年12月4日 星期三
java wav 轉 mp3
wav檔處理是OK的~ 不過因為檔案很大~ 不太適合做資訊發布...
所以最後發布就轉成mp3壓縮~
我這邊採用jave的lib...
http://www.sauronsoftware.it/projects/jave/
原因最主要也是輕量(只要一個jar)
win/centos通吃
可java呼叫
可以成功使用(重點)
呼叫的java sample code如下:
File source = new File(fin);
File target = new File(fout);
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(128000));
audio.setChannels(new Integer(2));
audio.setSamplingRate(new Integer(44100));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);
所以最後發布就轉成mp3壓縮~
我這邊採用jave的lib...
http://www.sauronsoftware.it/projects/jave/
原因最主要也是輕量(只要一個jar)
win/centos通吃
可java呼叫
可以成功使用(重點)
呼叫的java sample code如下:
File source = new File(fin);
File target = new File(fout);
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(128000));
audio.setChannels(new Integer(2));
audio.setSamplingRate(new Integer(44100));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);
java wav 計算db值
承上篇...
有計算音量的部分(算db值, 只是一個強度相對的大小值)
我忘了是從那邊copy出來的~
不過用google查該method name應該可以找到不少...
反正就把從WaveFile裡面讀到的raw data丟進去就有一個值生出來了XD"
主要計算db的method
/** Computes the RMS volume of a group of signal sizes ranging from -1 to 1. */
public double volumeRMS(double[] raw) {
double sum = 0d;
if (raw.length==0) {
return sum;
} else {
for (int ii=0; ii<raw.length; ii++) {
sum += raw[ii];
}
}
double average = sum/raw.length;
double sumMeanSquare = 0d;
for (int ii=0; ii<raw.length; ii++) {
sumMeanSquare += Math.pow(raw[ii]-average,2d);
}
double averageMeanSquare = sumMeanSquare/raw.length;
double rootMeanSquare = Math.pow(averageMeanSquare,0.5d);
return rootMeanSquare;
}
有計算音量的部分(算db值, 只是一個強度相對的大小值)
我忘了是從那邊copy出來的~
不過用google查該method name應該可以找到不少...
反正就把從WaveFile裡面讀到的raw data丟進去就有一個值生出來了XD"
主要計算db的method
/** Computes the RMS volume of a group of signal sizes ranging from -1 to 1. */
public double volumeRMS(double[] raw) {
double sum = 0d;
if (raw.length==0) {
return sum;
} else {
for (int ii=0; ii<raw.length; ii++) {
sum += raw[ii];
}
}
double average = sum/raw.length;
double sumMeanSquare = 0d;
for (int ii=0; ii<raw.length; ii++) {
sumMeanSquare += Math.pow(raw[ii]-average,2d);
}
double averageMeanSquare = sumMeanSquare/raw.length;
double rootMeanSquare = Math.pow(averageMeanSquare,0.5d);
return rootMeanSquare;
}
java WavFile 切檔案
處理wav檔資訊, 問google其實有不少的解決方案~
這次對於聲音採取lib的選擇順序重點是...
1. 要能動, 可以包成api呼叫
2. win/linex(centos) 都要相容
3. 以java原生/相關優先
4. 輕量/相依性較低
因為其實也不是只做一兩項處理而已~ ...每個人都說很簡單~
喵的~ 最好整四五個以上功能很簡單啦....
所以有很多有名的都不行T_T...
有名的大多都包成有UI了~ 很難從裡面拆method出來用@@...
我最後是採用一個有source檔的拿來回自己改...這個只能處理純wav...
有些運算可能不太正確~ 其原因為我並不了解wav本身的正確格式與內容~
不過就我需要的部分~ 能做到就好^^0....
選他是因為lib最單純(純java code, 不用lib/jar)~
然後有是有少數看懂source code用法|||Orz...
(某些lib/open source是看懂一半~ 硬改source code後就GG...因為套件流程綁太多~ 沒辦法一一找對地方改QQ)
先說明該source code的出處
http://www.labbookpages.co.uk/audio/javaWavFiles.html
至於應用上是拿來做兩件事
1. 處理切檔(ex: 2分鐘切出1分鐘)
2. 找音量相對大的位置(音量就等於內容資料強度...反正就是值越大, 音量越大)
合起來就變成~ 找出音量相對大的地方開始切N秒~ 成為新的wav檔案
這篇先放切檔案的method
基本上就是先建一個空的{secs}秒, wav, 然後從原本的wav檔, 某個位置開始讀寫...
有處理若是該位置是在原始檔的後面(會有可能造成只寫一部分的資料~ 但是新檔尾巴就空空的)
在原始檔長度小於新檔長度時就會丟excption出去了...(在偶低case裡, 原始檔長度不夠本來就不應該做處理)
/**cut wav file, start with buffersize * start, cut secs seconds
* @param wavFile source
* @param buffersize sample buffersize
* @param start idx of the sample
* @param secs cut how long seconds
* @param target output file path*/
public void process(WavFile wavFile, int buffersize, int start, double secs, String target) throws Exception {
WavFile newFile = null;
try {
long sampleRate = wavFile.getSampleRate(); // Samples per second
double totalsecs = wavFile.getNumFrames()/buffersize;
if(start+secs > totalsecs) {
start = (int)(totalsecs - secs);
}
if(start < 0) {
start = 0;
}
double duration = secs; // Seconds
// Calculate the number of frames required for specified duration
long numFrames = (long)(duration * sampleRate);
newFile = WavFile.newWavFile(new File(target),
wavFile.getNumChannels(),
numFrames,
wavFile.getValidBits(),
sampleRate);
// Display information about the wav file
//wavFile.display();
//System.out.println("-----------");
//newFile.display();
// Get the number of audio channels in the wav file
int numChannels = wavFile.getNumChannels();
int frames = buffersize;
// Create a buffer of 100 frames
double[][] buffer = new double[numChannels][frames];
int framesRead;
int loop = 0;
// Read frames into buffer
do {
framesRead = wavFile.readFrames(buffer, frames);
if(loop >= start) {
long remaining = newFile.getFramesRemaining();
int toWrite = (remaining > frames) ? frames : (int) remaining;
// Write the buffer
//newFile.writeFrames(buffer, toWrite);
newFile.writeFrames(buffer, toWrite);
if(toWrite < frames) {
break;
}
}
loop++;
} while (framesRead != 0) ;
} catch(Exception e) {
throw e;
} finally {
if(newFile != null) {
try { newFile.close(); } catch(Exception eee) {}
}
}
}
這次對於聲音採取lib的選擇順序重點是...
1. 要能動, 可以包成api呼叫
2. win/linex(centos) 都要相容
3. 以java原生/相關優先
4. 輕量/相依性較低
因為其實也不是只做一兩項處理而已~ ...每個人都說很簡單~
喵的~ 最好整四五個以上功能很簡單啦....
所以有很多有名的都不行T_T...
有名的大多都包成有UI了~ 很難從裡面拆method出來用@@...
我最後是採用一個有source檔的拿來回自己改...這個只能處理純wav...
有些運算可能不太正確~ 其原因為我並不了解wav本身的正確格式與內容~
不過就我需要的部分~ 能做到就好^^0....
選他是因為lib最單純(純java code, 不用lib/jar)~
然後有是有少數看懂source code用法|||Orz...
(某些lib/open source是看懂一半~ 硬改source code後就GG...因為套件流程綁太多~ 沒辦法一一找對地方改QQ)
先說明該source code的出處
http://www.labbookpages.co.uk/audio/javaWavFiles.html
至於應用上是拿來做兩件事
1. 處理切檔(ex: 2分鐘切出1分鐘)
2. 找音量相對大的位置(音量就等於內容資料強度...反正就是值越大, 音量越大)
合起來就變成~ 找出音量相對大的地方開始切N秒~ 成為新的wav檔案
這篇先放切檔案的method
基本上就是先建一個空的{secs}秒, wav, 然後從原本的wav檔, 某個位置開始讀寫...
有處理若是該位置是在原始檔的後面(會有可能造成只寫一部分的資料~ 但是新檔尾巴就空空的)
在原始檔長度小於新檔長度時就會丟excption出去了...(在偶低case裡, 原始檔長度不夠本來就不應該做處理)
/**cut wav file, start with buffersize * start, cut secs seconds
* @param wavFile source
* @param buffersize sample buffersize
* @param start idx of the sample
* @param secs cut how long seconds
* @param target output file path*/
public void process(WavFile wavFile, int buffersize, int start, double secs, String target) throws Exception {
WavFile newFile = null;
try {
long sampleRate = wavFile.getSampleRate(); // Samples per second
double totalsecs = wavFile.getNumFrames()/buffersize;
if(start+secs > totalsecs) {
start = (int)(totalsecs - secs);
}
if(start < 0) {
start = 0;
}
double duration = secs; // Seconds
// Calculate the number of frames required for specified duration
long numFrames = (long)(duration * sampleRate);
newFile = WavFile.newWavFile(new File(target),
wavFile.getNumChannels(),
numFrames,
wavFile.getValidBits(),
sampleRate);
// Display information about the wav file
//wavFile.display();
//System.out.println("-----------");
//newFile.display();
// Get the number of audio channels in the wav file
int numChannels = wavFile.getNumChannels();
int frames = buffersize;
// Create a buffer of 100 frames
double[][] buffer = new double[numChannels][frames];
int framesRead;
int loop = 0;
// Read frames into buffer
do {
framesRead = wavFile.readFrames(buffer, frames);
if(loop >= start) {
long remaining = newFile.getFramesRemaining();
int toWrite = (remaining > frames) ? frames : (int) remaining;
// Write the buffer
//newFile.writeFrames(buffer, toWrite);
newFile.writeFrames(buffer, toWrite);
if(toWrite < frames) {
break;
}
}
loop++;
} while (framesRead != 0) ;
} catch(Exception e) {
throw e;
} finally {
if(newFile != null) {
try { newFile.close(); } catch(Exception eee) {}
}
}
}
2013年10月29日 星期二
wav spectrum 頻譜圖 + python audiolab
因為這次要處理wav檔案資料...
其實py audiolab能處理上不止算頻譜,
只是其他的項目用Java解決掉~
就只有頻譜圖是用python...
(一來不會算頻譜, 二來Java繪圖的套件過於艱澀, py找來的資源就已經相當漂亮了Q_Q)
環境安裝貼在上一篇文...
先貼一張結果圖~
程式沒幾行, 過程是挺心酸的...Q_Q...
整個重點大概在於:
python 與相關應用module安裝...
找一段可以用的程式碼來打底...
(google audiolab+spectrum 應該就會有~我也是google來的)
調好圖表版面, 對齊(因有上下圖需要對齊的需求), 間隔, 顏色
(sample是2分鐘的wav, 但因實務上只使用大約30s, 所以才用5s做單位x軸)
解決中文字的問題....
(python原生沒中文, 最後採用指定TTF解決, 跨平台機器安裝才方便Q_Q)
原始碼
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
from pylab import *
import wave
import matplotlib.pyplot as plt
myfont = matplotlib.font_manager.FontProperties(fname='/etc/xxxx/MSJH.TTF')
infile = None
outfile = None
secInterval = 5 #x-axis interval
def show_wave_n_spec():
if(len(sys.argv) < 2) :
print('err input, plz input argv[1] and argv[2]')
return
infile = sys.argv[1]
outfile = sys.argv[2]
spf = wave.open(infile,'r')
f = spf.getframerate()
sound_info = spf.readframes(-1)
sound_info = fromstring(sound_info, 'Int16')
spflength = round(spf.getnframes()/f)
#print(spflength)
#print(sound_info)
#---------------pic1
ax = subplot(211)
title(u'Waveform(波形圖)',fontproperties=myfont)
plot(sound_info, '#5755FF')
xlim(0, len(sound_info))
plt.axis([0, len(sound_info), -15000, 15000])
grid(True)
#change axis-x position/text
xlabel2 = range(0, int(spflength+1), secInterval)
xposition2 = []
for x in xlabel2:
xposition2.append(x*f)
#print(xposition2)
ax.set_xticks(xposition2)
ax.set_xticklabels(xlabel2)
#change axis-y
ylabel2 = []
for x in ax.get_yticks() :
ylabel2.append(str(x/1000)+'k')
ax.set_yticklabels(ylabel2)
#---------------pic2
ax2 = subplot(212)
title(u'Spectrogram(頻譜圖)',fontproperties=myfont)
spectrogram = specgram(sound_info, Fs = f, scale_by_freq=True,sides='default')
plt.axis([0, spflength, 0, 20000])
ax2.set_xticks(xlabel2)
ax2.set_xticklabels(xlabel2)
grid(True)
ylabel2 = []
for x in ax2.get_yticks() :
ylabel2.append(str(x/1000)+'k')
ax2.set_yticklabels(ylabel2)
#show()
savefig(outfile);
spf.close()
show_wave_n_spec()
其實py audiolab能處理上不止算頻譜,
只是其他的項目用Java解決掉~
就只有頻譜圖是用python...
(一來不會算頻譜, 二來Java繪圖的套件過於艱澀, py找來的資源就已經相當漂亮了Q_Q)
環境安裝貼在上一篇文...
先貼一張結果圖~
程式沒幾行, 過程是挺心酸的...Q_Q...
整個重點大概在於:
python 與相關應用module安裝...
找一段可以用的程式碼來打底...
(google audiolab+spectrum 應該就會有~我也是google來的)
調好圖表版面, 對齊(因有上下圖需要對齊的需求), 間隔, 顏色
(sample是2分鐘的wav, 但因實務上只使用大約30s, 所以才用5s做單位x軸)
解決中文字的問題....
(python原生沒中文, 最後採用指定TTF解決, 跨平台機器安裝才方便Q_Q)
原始碼
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
from pylab import *
import wave
import matplotlib.pyplot as plt
myfont = matplotlib.font_manager.FontProperties(fname='/etc/xxxx/MSJH.TTF')
infile = None
outfile = None
secInterval = 5 #x-axis interval
def show_wave_n_spec():
if(len(sys.argv) < 2) :
print('err input, plz input argv[1] and argv[2]')
return
infile = sys.argv[1]
outfile = sys.argv[2]
spf = wave.open(infile,'r')
f = spf.getframerate()
sound_info = spf.readframes(-1)
sound_info = fromstring(sound_info, 'Int16')
spflength = round(spf.getnframes()/f)
#print(spflength)
#print(sound_info)
#---------------pic1
ax = subplot(211)
title(u'Waveform(波形圖)',fontproperties=myfont)
plot(sound_info, '#5755FF')
xlim(0, len(sound_info))
plt.axis([0, len(sound_info), -15000, 15000])
grid(True)
#change axis-x position/text
xlabel2 = range(0, int(spflength+1), secInterval)
xposition2 = []
for x in xlabel2:
xposition2.append(x*f)
#print(xposition2)
ax.set_xticks(xposition2)
ax.set_xticklabels(xlabel2)
#change axis-y
ylabel2 = []
for x in ax.get_yticks() :
ylabel2.append(str(x/1000)+'k')
ax.set_yticklabels(ylabel2)
#---------------pic2
ax2 = subplot(212)
title(u'Spectrogram(頻譜圖)',fontproperties=myfont)
spectrogram = specgram(sound_info, Fs = f, scale_by_freq=True,sides='default')
plt.axis([0, spflength, 0, 20000])
ax2.set_xticks(xlabel2)
ax2.set_xticklabels(xlabel2)
grid(True)
ylabel2 = []
for x in ax2.get_yticks() :
ylabel2.append(str(x/1000)+'k')
ax2.set_yticklabels(ylabel2)
#show()
savefig(outfile);
spf.close()
show_wave_n_spec()
訂閱:
意見 (Atom)


