mmfcc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c2d12ce70bab6304d063e738501344d110ebb087
4
+ data.tar.gz: df115cd944bedd7ac3d432a01346bd927909c419
5
+ SHA512:
6
+ metadata.gz: 209d10bd2cf1a88d339fe787d50ef44581e6243c5309fb767adb6d92806f5941abb3609eb28074c603493a814e41384911632ecae5cfc5603bceb8a69ab0e2e0
7
+ data.tar.gz: cc5b7b328fe53d3e039d5da16d150ddb59bda499a19ee6dcd0f1db18a3e7c7b2f96ade206811ff64d67cbde3e751852cc954df606acb4045b15354dd5ef5673c
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mmfcc.gemspec
4
+ gemspec
data/README.md ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/mmfcc ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pathname'
4
+ lib = Pathname.new(__FILE__).dirname.join('..', 'lib').expand_path
5
+ $LOAD_PATH.unshift lib.to_s
6
+
7
+ require 'mmfcc/command'
8
+ command = Mmfcc::Command.new
9
+ command.run
10
+
data/lib/mmfcc.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "mmfcc/version"
2
+
@@ -0,0 +1,85 @@
1
+
2
+ module Mmfcc
3
+ require "rubygems"
4
+ require "ai4r"
5
+
6
+ class Clustering
7
+
8
+ def initialize(cnum)
9
+ @cnum = cnum
10
+ end
11
+
12
+ def kmeans(all_mfcc, clusterNum)
13
+
14
+ ai4r_data = Ai4r::Data::DataSet.new(:data_items=> all_mfcc)
15
+
16
+ cluster = Ai4r::Clusterers::KMeans.new
17
+ cluster.build(ai4r_data, clusterNum)
18
+
19
+ return cluster
20
+ end
21
+
22
+ def loadMFCC(mfccFile, m, all_mfcc)
23
+
24
+ mfcc = []
25
+ mfccs = []
26
+
27
+ File.open(mfccFile, "r+b") {|f|
28
+ while line = f.read(4)
29
+ if line == "" then
30
+ break
31
+ end
32
+
33
+ val = line.unpack('f')[0]
34
+ mfcc.push(val)
35
+
36
+
37
+ if mfcc.length==m then
38
+ mfccs.push(mfcc)
39
+ all_mfcc.push(mfcc)
40
+ mfcc=[]
41
+ end
42
+ end
43
+ }
44
+
45
+ return mfccs
46
+ end
47
+
48
+ def run
49
+
50
+ mfccDir = './mfcc/'
51
+
52
+ clusterNum = @cnum.to_i
53
+ mfcc_dict = {}
54
+ all_mfcc = []
55
+
56
+ Find.find(mfccDir) {|mfccFile|
57
+ next unless mfccFile.end_with?(".mfc")
58
+ mfcc = loadMFCC(mfccFile, 20, all_mfcc)
59
+ mfcc_dict[mfccFile]=mfcc
60
+ }
61
+
62
+ cluster = kmeans(all_mfcc, clusterNum)
63
+
64
+ writeToFile = File.open("./histgram.txt",'w')
65
+
66
+ mfcc_dict.each{|key, value|
67
+ writeToFile.puts key
68
+
69
+ histgram = [0]*clusterNum
70
+
71
+ value.each{|d|
72
+ i = cluster.eval(d)
73
+ histgram[i]+=1
74
+ }
75
+
76
+ str_hist = histgram.join(" ")
77
+ writeToFile.puts str_hist
78
+
79
+ }
80
+
81
+ puts "histgram.txt is created."
82
+ writeToFile.close
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,29 @@
1
+ module Mmfcc
2
+ require "find"
3
+
4
+ class Command
5
+ def run
6
+ require 'optparse'
7
+
8
+ params = ARGV.getopts('mc',"type:mp3", "m4apath:./m4a/", "mp3path:./mp3/", "cnum:8")
9
+
10
+ if params["m"] then
11
+ puts "calculating mfcc..."
12
+
13
+ require 'mmfcc/mfcc'
14
+
15
+ mfcc = Mmfcc::Mfcc.new(params["type"], params["m4apath"], params["mp3path"])
16
+ mfcc.run
17
+ end
18
+
19
+ if params["c"] then
20
+ puts "start clustering..."
21
+
22
+ require 'mmfcc/clustering'
23
+
24
+ clustering = Mmfcc::Clustering.new(params["cnum"])
25
+ clustering.run
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/mmfcc/mfcc.rb ADDED
@@ -0,0 +1,148 @@
1
+
2
+ module Mmfcc
3
+ class Mfcc
4
+
5
+ def initialize(type, m4apath, mp3path)
6
+ @type = type
7
+ @m4apath = m4apath
8
+ @mp3path = mp3path
9
+ end
10
+
11
+ def m4aToRaw(m4aFile)
12
+ system("ffmpeg -i "+m4aFile+" -ab 32k -ar 16000 temp.m4a")
13
+ # decode mp3 to wav
14
+ system("ffmpeg -i temp.m4a temp.wav")
15
+ # convert wav to raw
16
+ system("sox temp.wav temp.raw")
17
+ # delete needless
18
+ system("rm temp.m4a")
19
+ system("rm temp.wav")
20
+ end
21
+
22
+ def mp3ToRaw(mp3File)
23
+ system("lame --resample 16 -b 32 -a "+mp3File+" temp.mp3")
24
+ # decode mp3 to wav
25
+ system("lame --decode temp.mp3 temp.wav")
26
+ # convert wav to raw
27
+ system("sox temp.wav temp.raw")
28
+ # delete needless
29
+ system("rm temp.mp3")
30
+ system("rm temp.wav")
31
+ end
32
+
33
+ def calcNumSample(rawFile)
34
+ # calculate byte
35
+ filesize = File.size?("temp.raw")
36
+ numsample = filesize / 2
37
+ return numsample
38
+ end
39
+
40
+ def extractCenter(inFile, outFile, period)
41
+ numsample = calcNumSample(inFile)
42
+ p numsample
43
+
44
+ fs = 16000
45
+ center = numsample / 2
46
+ start = center - fs * period
47
+ ends = center + fs * period
48
+
49
+ if start < 0 then
50
+ start = 0
51
+ end
52
+ if ends > numsample - 1 then
53
+ ends = numsample - 1
54
+ end
55
+
56
+ system("bcut +s -s "+start.to_s+" -e "+ends.to_s+" < temp.raw > "+outFile)
57
+ end
58
+
59
+ def calcMFCC(rawFile, mfccFile)
60
+ # sampling rate: 16kHz
61
+ # frame length: 400
62
+ # shift broad: 160
63
+ # num of channel: 40
64
+ # MFCC: 19 dimentions + energy
65
+ system("x2x +sf < "+rawFile+" | frame -l 400 -p 160 | mfcc -l 400 -f 16 -n 40 -m 19 -E > "+mfccFile)
66
+ end
67
+
68
+ def run
69
+
70
+ m4aDir = @m4apath
71
+ mp3Dir = @mp3path
72
+ mfccDir = './mfcc/'
73
+ rawDir = './raw/'
74
+
75
+ if not Dir::exist?(mfccDir) then
76
+ Dir::mkdir(mfccDir)
77
+ end
78
+ if not Dir::exist?(rawDir) then
79
+ Dir::mkdir(rawDir)
80
+ end
81
+
82
+ if @type == "m4a" then
83
+
84
+ if not Dir::exist?(m4aDir) then
85
+ raise "there is no directry for m4a. Please make directry ./m4a/"
86
+ end
87
+
88
+ Find.find(m4aDir) {|m4aFile|
89
+ next unless FileTest.file?(m4aFile)
90
+ next unless m4aFile.end_with?(".m4a")
91
+
92
+ mfccFile = m4aFile.sub(".m4a",".mfc")
93
+ mfccFile = mfccFile.sub(m4aDir, mfccDir)
94
+
95
+ rawFile = m4aFile.sub(".m4a",".raw")
96
+ rawFile = rawFile.sub(m4aDir, rawDir)
97
+
98
+ begin
99
+ # decode MP3
100
+ m4aToRaw(m4aFile)
101
+
102
+ # convert 30s mp3 to rawFile
103
+ extractCenter("temp.raw", rawFile, 15)
104
+
105
+ calcMFCC(rawFile, mfccFile)
106
+
107
+ system("rm temp.raw")
108
+ rescue
109
+ next
110
+ puts "failed at decode m4a"
111
+ end
112
+ }
113
+ else
114
+
115
+ if not Dir::exist?(mp3Dir) then
116
+ raise "there is no directry for mp3. Please make directry ./mp3/"
117
+ end
118
+
119
+ Find.find(mp3Dir) {|mp3File|
120
+ next unless FileTest.file?(mp3File)
121
+ next unless mp3File.end_with?(".mp3")
122
+
123
+ mfccFile = mp3File.sub(".mp3",".mfc")
124
+ mfccFile = mfccFile.sub(mp3Dir, mfccDir)
125
+
126
+ rawFile = mp3File.sub(".mp3",".raw")
127
+ rawFile = rawFile.sub(mp3Dir, rawDir)
128
+
129
+ begin
130
+ # decode MP3
131
+ mp3ToRaw(mp3File)
132
+
133
+ # convert 30s mp3 to rawFile
134
+ extractCenter("temp.raw", rawFile, 15)
135
+
136
+ calcMFCC(rawFile, mfccFile)
137
+
138
+ system("rm temp.raw")
139
+ rescue
140
+ next
141
+ puts "failed at decode mp3"
142
+ end
143
+ }
144
+
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,3 @@
1
+ module Mmfcc
2
+ VERSION = "0.0.1"
3
+ end
data/mmfcc.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mmfcc/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mmfcc"
7
+ s.version = Mmfcc::VERSION
8
+ s.authors = ["RittaNarita"]
9
+ s.email = ["narittan@gmail.com"]
10
+ s.homepage = "https://github.com/RittaNarita/Mmfcc"
11
+ s.summary = %q{the tool for making mfcc of songs}
12
+ s.description = %q{you can make the Mel-frequency cepstrum, which is a feature spectrum of a song. }
13
+ s.license = "GPLv2"
14
+ s.rubyforge_project = "mmfcc"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "ai4r", '~> 0'
23
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mmfcc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - RittaNarita
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ai4r
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: 'you can make the Mel-frequency cepstrum, which is a feature spectrum
28
+ of a song. '
29
+ email:
30
+ - narittan@gmail.com
31
+ executables:
32
+ - mmfcc
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - ".gitignore"
37
+ - Gemfile
38
+ - README.md
39
+ - Rakefile
40
+ - bin/mmfcc
41
+ - lib/mmfcc.rb
42
+ - lib/mmfcc/clustering.rb
43
+ - lib/mmfcc/command.rb
44
+ - lib/mmfcc/mfcc.rb
45
+ - lib/mmfcc/version.rb
46
+ - mmfcc.gemspec
47
+ homepage: https://github.com/RittaNarita/Mmfcc
48
+ licenses:
49
+ - GPLv2
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project: mmfcc
67
+ rubygems_version: 2.2.0
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: the tool for making mfcc of songs
71
+ test_files: []