Created
July 14, 2017 07:40
-
-
Save ikumasa/db93b3082afcd07ec8a0368108a5184a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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