Class: Wavfile

Inherits:
Object
  • Object
show all
Defined in:
lib/WavReader/wavfile.rb

Overview

Wavfile class, used to read an audio wav file It is able to read wav files with:

  • Any sampling frequency

  • Any number of channels

  • PCM 8,16,24 bits per sample

  • FLOAT 32 bits per sample

*Headers of 16, 18, 40 bytes

Instance Method Summary collapse

Constructor Details

#initialize(filename) ⇒ Wavfile

Initialize wavreader

Parameters:

  • filename (String)

    sets the path audio file to read. Example “c:audiotest.wav”



16
17
18
19
20
21
22
23
# File 'lib/WavReader/wavfile.rb', line 16

def initialize(filename)
	@filename = filename
	@mainheader = nil
	@logger = nil
	@wavfile = nil
	
	@lHeaderOffsetbytes = 0;
end

Instance Method Details

#CloseObject

Close the audio opened file



129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/WavReader/wavfile.rb', line 129

def Close	
	Log(Logger::DEBUG,"Start closing #{@filename}")

	if (@wavfile != nil)
		@wavfile.close
		@wavfile = nil
	end 
	
	Log(Logger::DEBUG,"Closed: #{@filename}")
	
	@filename = nil
end

#GetAudioSamples(sampleindex, bNormalize = true) ⇒ Array

Returns audio samples array

Parameters:

  • n (int)

    sample index (starts in n = 0)

  • bNormalize (Bollean) (defaults to: true)

    if normalize == true the returned samples are normalized (max value = 1.0), if not the original readed value us returned

Returns:

  • (Array)

    with audio samples (1 sample per channel). Example [0.323 0.322]



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/WavReader/wavfile.rb', line 60

def GetAudioSamples (sampleindex, bNormalize = true)
	if (@wavfile == nil)
		Log(Logger::WARN, "The file is not opened")
	else
		Log(Logger::DEBUG,"Start reading sample pos #{@sampleindex}")
		
		#Seek to sample position channel 0
		lsamplesizebytes = (@mainheader.sBitsPerSample / 8)
		loffsetbytes = @lHeaderOffsetbytes + sampleindex * (@mainheader.nchannels * lsamplesizebytes)
		
		Log(Logger::DEBUG,"loffsetbytes: #{loffsetbytes} of #{@wavfile.size}")
					
		if (loffsetbytes >= @wavfile.size)
		  Log(Logger::DEBUG,"EOF reached!")
			nil
		else
			@wavfile.seek(loffsetbytes)
		
			#Create PCM samples
			samples = nil
			nmax = 1;
			
			if (@mainheader.nformattag == Wavheader::PCM)
				#Read PCM sample 8 bits/sample (-128 ... 0 ... +127)
				if (@mainheader.sBitsPerSample == 8)
					samples = Wavsample8b.new(:num_channels => @mainheader.nchannels)
					nmax = 128
				end
				#Read PCM sample 16 bits/sample (-32768 ... 0 ... +32767)
				if (@mainheader.sBitsPerSample == 16)
					samples = Wavsample16b.new(:num_channels => @mainheader.nchannels)
					nmax = 32768
				end
				#Read PCM sample 24 bits/sample (-8388608 ... 0 ... +8388607)
				if (@mainheader.sBitsPerSample == 24)
					samples = Wavsample24b.new(:num_channels => @mainheader.nchannels)
					nmax = 8388608
				end										
			end

			#Create FLOAT samples
			if (@mainheader.nformattag == Wavheader::FLOAT)				
				samples = WavsampleFloat.new(:num_channels => @mainheader.nchannels)
			end
			
			if (samples != nil)				
				#Read sample from file
				samples.read(@wavfile)
			else
				raise 'Sample not compatible (Is not PCM neither FLOAT)'
			end
			
			Log(Logger::DEBUG,samples)
			
			samplesRetArray = samples.samples
			
			if (samplesRetArray != nil) and (@mainheader.nformattag == Wavheader::PCM) and (bNormalize == true)
         samplesRetArray = samplesRetArray.collect {|x| x.to_f / nmax.to_f}
			end
       
       Log(Logger::DEBUG,"Samples normalized = #{samplesRetArray.to_s}")
       
       samplesRetArray 
       					
		end
	end 
end

#GetFileInfoArray

Returns audio file information

Returns:

  • (Array)

    with sampling frecuency and number of channels [fs nch]



52
53
54
# File 'lib/WavReader/wavfile.rb', line 52

def GetFileInfo 
  return [@mainheader.ulSampleRate,@mainheader.nchannels] 
end

#ReadHeaderObject

Reads the wav header file



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/WavReader/wavfile.rb', line 32

def ReadHeader
	Log(Logger::DEBUG,"Start reading wav header of #{@filename}")
	  
	#Read wav header
	@mainheader = nil
	@mainheader = Wavheader.new

	@wavfile = File.open(@filename, 'r')
	@mainheader.read(@wavfile)
	
	@lHeaderOffsetbytes = @mainheader.cfirstdatabyte.abs_offset;
	
	Log(Logger::DEBUG,"lHeaderOffsetbytes:  #{@lHeaderOffsetbytes}")
			
	Log(Logger::DEBUG,@mainheader)
				
end

#Setlogger(logger) ⇒ Object

Set logger (optional)

Parameters:

  • logger (Logger)

    a referce to Logger class



27
28
29
# File 'lib/WavReader/wavfile.rb', line 27

def Setlogger(logger)
	@logger = logger
end