JOCLoudness 1.0.2 → 1.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3df471c2ebdf1e1e25de968b5ab074a267a79a05
4
- data.tar.gz: 9d13fc517b4901bde3e184692a62aefa2e2e3d99
3
+ metadata.gz: 0cd5d2552d8fb90f3fbc2eadfaa80d37285c3120
4
+ data.tar.gz: dc05cf8feb070410238e93fcb6a08899a96efccd
5
5
  SHA512:
6
- metadata.gz: cdb7f39ba81828c04f7bef651ee9bd7b733a2c353e745d0a05be8cb71b53d73cbca896f6fc8e2b04e25f3a9edc8bbb9df02cfc720aa3162694d389d654013330
7
- data.tar.gz: 27e15a6d9dd5bd67a4f5eb5d680f9659fa393e83fb811de19693d74bdecec1de2048f75339c21996a5158592936e0c8b90d4b5915c52aa0da49e0b5cc58f603d
6
+ metadata.gz: 44d689ed177c7115f5a94b6fa7dbb0222fd1032070b8a677e61f478e33a2cf33dfefa6019b4a96e092c061e17d565763870367d69c85b3062f918a3b34946fd9
7
+ data.tar.gz: 3bf8dc5ea09ce4ecd48d0762200b41a13fd5f7a16ff17dbfb5ad45604b9265086a8ab96e28fc695f49642e1b38f65e31661cfb30e4ec0e5a9145c2a5ae86011e
@@ -0,0 +1,173 @@
1
+ #file: wavfile.rb
2
+ require_relative './wavheader'
3
+ require_relative './wavsamples'
4
+
5
+ #Wavfile class, used to read an audio wav file
6
+ #It is able to read wav files with:
7
+ #* Any sampling frequency
8
+ #* Any number of channels
9
+ #* PCM 8,16,24 bits per sample
10
+ #* FLOAT 36 bits per sample
11
+ #*Headers of 16, 18, 40 bytes
12
+ class Wavfile
13
+
14
+ #Initialize wavreader
15
+ # @param filename [String] sets the path audio file to read. Example "c:\audio\test.wav"
16
+ def initialize(filename)
17
+ @filename = filename
18
+ @mainheader = nil
19
+ @logger = nil
20
+ @wavfile = nil
21
+
22
+ @lHeaderOffsetbytes = 0;
23
+ end
24
+
25
+ # Set logger (optional)
26
+ # @param logger [Logger] a referce to Logger class
27
+ def Setlogger(logger)
28
+ @logger = logger
29
+ end
30
+
31
+ # Reads the wav header file
32
+ def ReadHeader
33
+ Log(Logger::DEBUG,"Start reading wav header of #{@filename}")
34
+
35
+ begin
36
+ #Read wav header
37
+ @mainheader = nil
38
+ @mainheader = Wavheader.new
39
+
40
+ @wavfile = File.open(@filename, 'r')
41
+ @mainheader.read(@wavfile)
42
+
43
+ @lHeaderOffsetbytes = @mainheader.cfirstdatabyte.abs_offset;
44
+
45
+ Log(Logger::DEBUG,"lHeaderOffsetbytes: #{@lHeaderOffsetbytes}")
46
+
47
+ rescue Exception => e
48
+ Log(Logger::ERROR,"Error reading wav header of #{e.message}, Trace: #{e.backtrace.inspect}")
49
+ end
50
+
51
+ Log(Logger::DEBUG,@mainheader)
52
+
53
+ end
54
+
55
+ # Returns audio file information
56
+ # @return [Array] with sampling frecuency and number of channels [fs nch]
57
+ def GetFileInfo
58
+ return [@mainheader.ulSampleRate,@mainheader.nchannels]
59
+ end
60
+
61
+ # Returns audio samples array
62
+ # @param n [int] sample index (starts in n = 0)
63
+ # @param bNormalize [Bollean] if normalize == true the returned samples are normalized (max value = 1.0), if not the original readed value us returned
64
+ # @return [Array] with audio samples (1 sample per channel). Example [0.323 0.322]
65
+ def GetAudioSamples (sampleindex, bNormalize = true)
66
+ if (@wavfile == nil)
67
+ Log(Logger::WARN, "The file is not opened")
68
+ else
69
+ begin
70
+ Log(Logger::DEBUG,"Start reading sample pos #{@sampleindex}")
71
+
72
+ #Seek to sample position channel 0
73
+ lsamplesizebytes = (@mainheader.sBitsPerSample / 8)
74
+ loffsetbytes = @lHeaderOffsetbytes + sampleindex * (@mainheader.nchannels * lsamplesizebytes)
75
+
76
+ Log(Logger::DEBUG,"loffsetbytes: #{loffsetbytes} of #{@wavfile.size}")
77
+
78
+ if (loffsetbytes >= @wavfile.size)
79
+ Log(Logger::DEBUG,"EOF reached!")
80
+ nil
81
+ else
82
+ @wavfile.seek(loffsetbytes)
83
+
84
+ #Create PCM samples
85
+ samples = nil
86
+ nmax = 1;
87
+
88
+ if (@mainheader.nformattag == Wavheader::PCM)
89
+ #Read PCM sample 8 bits/sample (-128 ... 0 ... +127)
90
+ if (@mainheader.sBitsPerSample == 8)
91
+ samples = Wavsample8b.new(:num_channels => @mainheader.nchannels)
92
+ nmax = 128
93
+ end
94
+ #Read PCM sample 16 bits/sample (-32768 ... 0 ... +32767)
95
+ if (@mainheader.sBitsPerSample == 16)
96
+ samples = Wavsample16b.new(:num_channels => @mainheader.nchannels)
97
+ nmax = 32768
98
+ end
99
+ #Read PCM sample 24 bits/sample (-8388608 ... 0 ... +8388607)
100
+ if (@mainheader.sBitsPerSample == 24)
101
+ samples = Wavsample24b.new(:num_channels => @mainheader.nchannels)
102
+ nmax = 8388608
103
+ end
104
+ end
105
+
106
+ #Create FLOAT samples
107
+ if (@mainheader.nformattag == Wavheader::FLOAT)
108
+ samples = WavsampleFloat.new(:num_channels => @mainheader.nchannels)
109
+ end
110
+
111
+ if (samples != nil)
112
+ #Read sample from file
113
+ samples.read(@wavfile)
114
+ else
115
+ raise 'Sample not compatible (Is not PCM neither FLOAT)'
116
+ end
117
+
118
+ Log(Logger::DEBUG,samples)
119
+
120
+ samplesRetArray = samples.samples
121
+
122
+ if (samplesRetArray != nil) and (@mainheader.nformattag == Wavheader::PCM) and (bNormalize == true)
123
+ samplesRetArray = samplesRetArray.collect {|x| x.to_f / nmax.to_f}
124
+ end
125
+
126
+ Log(Logger::DEBUG,"Samples normalized = #{samplesRetArray.to_s}")
127
+
128
+ samplesRetArray
129
+
130
+ end
131
+ rescue Exception => e
132
+ Log(Logger::ERROR,"Error reading wav sample in pos #{sampleindex}. Error: #{e.message}, Trace: #{e.backtrace.inspect}")
133
+ end
134
+ end
135
+ end
136
+
137
+ # Close the audio opened file
138
+ def Close
139
+ Log(Logger::DEBUG,"Start closing #{@filename}")
140
+
141
+ if (@wavfile != nil)
142
+ @wavfile.close
143
+ @wavfile = nil
144
+ end
145
+
146
+ Log(Logger::DEBUG,"Closed: #{@filename}")
147
+
148
+ @filename = nil
149
+ end
150
+
151
+ private
152
+
153
+ def Log (type, message)
154
+
155
+ if (@logger != nil)
156
+ if (type == Logger::FATAL)
157
+ @logger.fatal(message)
158
+ end
159
+ if (type == Logger::ERROR)
160
+ @logger.error(message)
161
+ end
162
+ if (type == Logger::WARN)
163
+ @logger.warn(message)
164
+ end
165
+ if (type == Logger::INFO)
166
+ @logger.info(message)
167
+ end
168
+ if (type == Logger::DEBUG)
169
+ @logger.debug(message)
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,47 @@
1
+ #file: wavheader.rb
2
+ require 'bindata'
3
+
4
+ # define main wav header
5
+ class Wavheader < BinData::Record
6
+ hide :cfirstdatabyte
7
+
8
+ PCM = 1
9
+ FLOAT = 3
10
+
11
+ #WAV header
12
+ endian :little
13
+
14
+ string :cid, :read_length => 4, :asserted_value => 'RIFF'
15
+ uint32 :ulChunksSizeTotal
16
+ string :cidwave, :read_length => 4, :asserted_value => 'WAVE'
17
+ string :cidfmt, :read_length => 4, :asserted_value => 'fmt '
18
+ uint32 :ulChunkSize
19
+
20
+ uint16 :nformattag #1 = PCM, 2 = FLOAT
21
+ uint16 :nchannels #Number of channels
22
+ uint32 :ulSampleRate #Sample rate
23
+ uint32 :ulAvgBytesSec #Bytes per sec avg
24
+ uint16 :sBlockAlign #Bytes x sample * num channels
25
+ uint16 :sBitsPerSample #bits per sample
26
+
27
+ # The following fields are optional depending on ulChunkSize
28
+
29
+ struct :subheader18, :onlyif => lambda {ulChunkSize == 18} do
30
+ uint16 :sSizeofExtension #Must be 2 end
31
+ end
32
+
33
+ struct :subheader40, :onlyif => lambda {ulChunkSize == 40} do
34
+ uint16 :sSizeofExtension, :asserted_value => 22
35
+ uint16 :sValidbitspersample #Valid bits per sample
36
+ uint32 :ulChannelmask #Speaker position mask (Use to be 0)
37
+ string :cGuidSubFormat, :read_length => 16 #GUID data format code
38
+ string :cfact, :read_length => 4, :asserted_value => 'fact'
39
+ uint32 :lChunkFactSize, :read_length => 4, :asserted_value => 4
40
+ uint32 :lSampleLength, :read_length => 4 #Number of samples (per channel)
41
+ end
42
+
43
+ string :cdata, :read_length => 4, :asserted_value => 'data'
44
+ uint32 :uDataChunkSize
45
+
46
+ uint8 :cfirstdatabyte
47
+ end
@@ -0,0 +1,46 @@
1
+ #file: wavsamples.rb
2
+ require 'bindata'
3
+
4
+ # define wav 8b per sample
5
+ class Wavsample8b < BinData::Record
6
+ #WAV sample 8bits per sample
7
+ mandatory_parameter :num_channels
8
+ endian :little
9
+
10
+ array :samples, :initial_length => :num_channels do
11
+ int8 :s
12
+ end
13
+ end
14
+
15
+ # define wav 16b per sample
16
+ class Wavsample16b < BinData::Record
17
+ #WAV sample 16bits per sample
18
+ mandatory_parameter :num_channels
19
+ endian :little
20
+
21
+ array :samples, :initial_length => :num_channels do
22
+ int16 :s
23
+ end
24
+ end
25
+
26
+ # define wav 24b per sample
27
+ class Wavsample24b < BinData::Record
28
+ #WAV sample 24bits per sample
29
+ mandatory_parameter :num_channels
30
+ endian :little
31
+
32
+ array :samples, :initial_length => :num_channels do
33
+ int24 :s
34
+ end
35
+ end
36
+
37
+ # define wav IEEE FLOAT per sample
38
+ class WavsampleFloat < BinData::Record
39
+ #WAV sample FLOAT
40
+ mandatory_parameter :num_channels
41
+ endian :little
42
+
43
+ array :samples, :initial_length => :num_channels do
44
+ float :s
45
+ end
46
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: JOCLoudness
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordi Cenzano
@@ -44,6 +44,9 @@ files:
44
44
  - lib/Loudness/Mean/MeanFast.rb
45
45
  - lib/Loudness/PreFilter/PREFilter.rb
46
46
  - lib/Loudness/RlbFilter/RLBFilter.rb
47
+ - lib/WavReader/wavfile.rb
48
+ - lib/WavReader/wavheader.rb
49
+ - lib/WavReader/wavsamples.rb
47
50
  homepage: http://rubygems.org/gems/JOCLoudness
48
51
  licenses:
49
52
  - MIT