Skip to content

Instantly share code, notes, and snippets.

@ikumasa
Created July 14, 2017 07:40
Show Gist options
  • Save ikumasa/db93b3082afcd07ec8a0368108a5184a to your computer and use it in GitHub Desktop.
Save ikumasa/db93b3082afcd07ec8a0368108a5184a to your computer and use it in GitHub Desktop.
package org.gennai.audio_analyzer.analysis;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.gennai.audio_analyzer.analysis.AudioTest.Audio;
import org.gennai.audio_analyzer.analysis.audio.AudioSamples;
import org.gennai.audio_analyzer.analysis.config.FingerprintConfig;
import org.gennai.audio_analyzer.analysis.config.QueryConfig;
import org.gennai.audio_analyzer.analysis.dao.IModelReference;
import org.gennai.audio_analyzer.analysis.dao.data.SoundData;
import org.gennai.audio_analyzer.analysis.data.Fingerprint;
import org.gennai.audio_analyzer.analysis.data.HashedFingerprint;
import org.gennai.audio_analyzer.analysis.hash.LocalitySensitiveHashingAlgorithm;
import org.gennai.audio_analyzer.analysis.inmemory.InMemoryModelService;
import org.gennai.audio_analyzer.analysis.inmemory.RAMStorage;
import org.gennai.audio_analyzer.analysis.query.QueryResult;
import org.gennai.audio_analyzer.analysis.query.ResultEntry;
public class WaveletsSample {
private FingerprintConfig fingerprintConfig;
private ModelService modelService;
private FingerprintService fingerprintService;
private LocalitySensitiveHashingAlgorithm lshAlgorithm;
private QueryConfig queryConfig;
private QueryFingerprintService queryFingerprintService;
private WaveletsSample() {
// 設定
fingerprintConfig = new FingerprintConfig();
fingerprintConfig.setTopWavelets(4000);
/*
fingerprintConfig.setNormalizeSignal(false);
fingerprintConfig.getSpectrogramConfig().setWdftSize(2048);
fingerprintConfig.getSpectrogramConfig().setOverlap(64);
fingerprintConfig.getSpectrogramConfig().setFrequencyRange(318, 40000);
fingerprintConfig.getSpectrogramConfig().setLogBins(32);
fingerprintConfig.getSpectrogramConfig().setImageLength(128);
*/
queryConfig = new QueryConfig();
/*
queryConfig.setThresholdVotes(5);
queryConfig.setMaxSoundsToReturn(25);
*/
// InMemory モデル
RAMStorage storage = new RAMStorage(
fingerprintConfig.getHashingConfig().getNumberOfLSHTables());
modelService = new InMemoryModelService(storage);
fingerprintService = new FingerprintService();
lshAlgorithm = new LocalitySensitiveHashingAlgorithm();
queryFingerprintService = new QueryFingerprintService();
}
private void insertHashData(String wavFile)
throws UnsupportedAudioFileException, IOException, LineUnavailableException {
// WAVEファイル読み込み
Audio audio = AudioTest.readWave(wavFile);
// audio.getData() -> データ(double 配列)
// audio.getOrigin() -> ファイルパス
// audio.getFormat() -> AudioFormat(Android では MediaFormat に)
AudioSamples audioSamples = new AudioSamples(audio.getData(), audio.getOrigin(),
(int) audio.getFormat().getSampleRate());
// Fingerprint 作成
List<Fingerprint> fingerprints = fingerprintService.createFingerprints(audioSamples,
fingerprintConfig);
// Hashed fingerprint 作成
List<HashedFingerprint> hashedFingerprints = fingerprints.parallelStream()
.map(fingerprint -> lshAlgorithm.hash(fingerprint,
fingerprintConfig.getHashingConfig().getNumberOfLSHTables(),
fingerprintConfig.getHashingConfig().getNumberOfMinHashesPerTable(),
fingerprintConfig.getClusters()))
.collect(Collectors.toList());
// メタデータをモデルに登録
// 再生秒数は必須
double length = (double) audio.getData().length / audio.getFormat().getSampleRate()
/ audio.getFormat().getChannels();
// メタデータのリファレンスが返る
IModelReference<?> soundReference = modelService.saveSound(new SoundData(length));
// Hashed fingerprint をモデルに登録
modelService.insertHashDataForSound(hashedFingerprints, soundReference);
}
private void query(String wavFile)
throws UnsupportedAudioFileException, IOException, LineUnavailableException {
// WAVEファイル読み込み
Audio audio = AudioTest.readWave(wavFile);
AudioSamples audioSamples = new AudioSamples(audio.getData(), audio.getOrigin(),
(int) audio.getFormat().getSampleRate());
// Fingerprint 作成
List<Fingerprint> fingerprints = fingerprintService.createFingerprints(audioSamples,
fingerprintConfig);
// Fingerprint を Hashed fingerprint に変換
List<HashedFingerprint> hashedFingerprints = fingerprints.parallelStream()
.map(fingerprint -> lshAlgorithm.hash(fingerprint,
fingerprintConfig.getHashingConfig().getNumberOfLSHTables(),
fingerprintConfig.getHashingConfig().getNumberOfMinHashesPerTable(),
fingerprintConfig.getClusters()))
.collect(Collectors.toList());
// モデルを検索
QueryResult queryResult = queryFingerprintService.query(hashedFingerprints, queryConfig,
modelService);
// ヒットしたか?
if (queryResult.containsMatches()) {
// ベストマッチ
ResultEntry resultEntry = queryResult.bestMatch();
System.out.printf("best id: %d, score: %d\n",
resultEntry.getSound().getSoundReference().getId(),
resultEntry.getHammingSimilaritySum());
// マッチリスト
queryResult.getResultEntries().forEach(entry -> {
System.out.printf("id: %d, score: %d\n",
entry.getSound().getSoundReference().getId(), entry.getHammingSimilaritySum());
});
} else {
System.out.println("no match");
}
}
public static void main(String[] args)
throws UnsupportedAudioFileException, IOException, LineUnavailableException {
WaveletsSample waveletsSample = new WaveletsSample();
waveletsSample.insertHashData("../samples4/nom1.wav");
waveletsSample.query("../samples4/nom1.wav");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment