處理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) {}
}
}
}
沒有留言:
張貼留言