File: AudioFileReading_example.cxx

package info (click to toggle)
clam 1.4.0-6
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 17,836 kB
  • ctags: 20,981
  • sloc: cpp: 92,504; python: 9,721; ansic: 1,602; xml: 444; sh: 239; makefile: 153; perl: 54; asm: 15
file content (149 lines) | stat: -rw-r--r-- 5,215 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
 *                         UNIVERSITAT POMPEU FABRA
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

// Welcome to the "AudioFileReading" example. In this example, we will show you
// how to use CLAM::MultiChannelAudioFileReader, a Processing that allows to read
// simultaneously several channels at once from the same file.
//
// Before attempting to follow this example you should take a look first on
// the "FileInfo" example ( examples/FileInfo_example.cxx )

// We must include these headers to have access to classes
// AudioFile, MultiChannelAudioFileReader and MultiChannelAudioFileReaderConfig
#include <iostream>
#include "AudioFile.hxx"
#include "MultiChannelAudioFileReader.hxx"
// Also we need the declaration of CLAM::Audio object, the object which
// represents an ( or portion of an ) audio signal
#include "Audio.hxx"
// For accessing <cmath> header in a cross-platform way
#include "CLAM_Math.hxx"
#include "DataTypes.hxx"

#include <vector>

int main( int argc, char** argv )
{
	// As we did in the FileInfo example we will take the input file from
	// the command line.

	if ( argc == 1 ) // No input file
	{
		std::cerr << "No input file" << std::endl;
		std::cerr << "Usage: AudioFileReading <input file name>" << std::endl;

		exit( - 1 );
	}
	else if ( argc > 2 ) // Too many parameters
	{
		std::cerr << "Too many parameters" << std::endl;
		std::cerr << "Usage: AudioFileReading <input file name>" << std::endl;
		
		exit( -1 );
	}
	
	// Now we are pretty sure that argv[1] holds a parameter.
	// We create a configuration for the MultiChannelAudioFileReader,
	// which will read the samples from the file
	CLAM::MultiChannelAudioFileReaderConfig cfg;
	// We set the 'SourceFile' config attribute to the parameter we received
	cfg.SetSourceFile( argv[1] );
	// Intantiate the processing
	CLAM::MultiChannelAudioFileReader reader;

	// And configure it
	if ( !reader.Configure(cfg) ) 
	{
		std::cerr
			<< "Error opening file: " << cfg.GetSourceFile() << std::endl
			<< reader.GetConfigErrorMessage() << std::endl;
		exit(-1);
	}

	// First of all, we must decide which will be our 'read size' i.e. the number
	// of samples we will want to get from each channel at once.
	const CLAM::TSize readSize = 1024;

	// And now we must setup the CLAM::Audio to hold the incoming samples from
	// each file channel.
	std::vector<CLAM::Audio> outputs;
	outputs.resize( reader.GetHeader().GetChannels() );

	// And now we set the size of each Audio object to our intended 'read size'
	for ( unsigned i = 0; i < outputs.size(); i++ )
	{
		outputs[i].SetSize( readSize );
	}

	// Now we can safely Start() the processing
	reader.Start();

	// We will implement a crappy text-based VUmeter just to some elementary
	// aspects of working with Audio's. What's a VUmeter? A vumeter is just
	// sort of gauge that indicates the loudness of a given signal. This
	// 'loudness' can be computed for each samples as:
	//     loudness[ n ] = 20. * log10( fabs( x[n] ) )
	// Note that this will give a number in the [0,-inf] range, in dB scale. What
	// is interesting is to see which is the range of this loudness for a given
	// audio fragment: it might be understood as a measure of how 'loud' is
	// that fragment.

	// We will use this counter for tracking the current frame index
	CLAM::TIndex frameCount = 1;

	// When will the loop end? Whenever the EOF is reached ;) i.e. when the Processing
	// cannot generate any more Audio objects.
	while ( reader.Do( outputs ) )
	{
		std::cout << "At frame #" << frameCount << std::endl;

		for ( unsigned int i = 0; i < outputs.size(); i++ )
		{
			std::cout << "Channel #" << i << " ";

			// We take the first sample loudness as both minimum and maximum
			CLAM::TData currentMax = 20. * log10( fabs(outputs[i].GetBuffer()[0]));
			CLAM::TData currentMin = 20. * log10( fabs(outputs[i].GetBuffer()[0]));
			
			// Simple min&max search loop: we compute loudness for each sample
			// in the fragment and check it against the current max and min
			for ( int n = 1; n < outputs[i].GetSize(); n++ )
			{
				CLAM::TData loudness = 20. * log10( fabs(outputs[i].GetBuffer()[n]) );
				if ( loudness >= currentMax )
					currentMax = loudness;
				if ( loudness <= currentMin )
					currentMin = loudness;
			}
			
			// we print out the pair of (max,min) loudness values
			std::cout << "( " << currentMax << " dB, " << currentMin << " dB)" << std::endl;
		}
		
		frameCount++;
	}

	// And stop it:
	reader.Stop();
	
	return 0;
}