CLAM-Development  1.4.0
MonoAudioFileReader.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "MonoAudioFileReader.hxx"
23 #include "AudioCodecs_Stream.hxx"
24 #include "ProcessingFactory.hxx"
25 
26 
27 namespace CLAM
28 {
29 
30 namespace Hidden
31 {
32  static const char * metadata[] = {
33  "key", "MonoAudioFileReader",
34  "category", "Audio File I/O",
35  "description", "MonoAudioFileReader",
36  0
37  };
38  static FactoryRegistrator<ProcessingFactory, MonoAudioFileReader> reg = metadata;
39 }
40 
41 
43  : mOutput( "Samples Read", this )
44  , mSeekControl( "Seek", this)
45  , mTimeOutput( "Current Time Position", this)
46  , mFramePositionOutput( "Current Frame Position", this)
47  , mProgressOutput( "Progress", this)
48  , mNativeStream( NULL )
49  {
50  Configure( cfg );
51  mSeekControl.SetBounds(0.,1.);
52  }
53 
55  {
56  if ( mNativeStream )
57  delete mNativeStream;
58  }
59 
61  {
62  return "MonoAudioFileReader";
63  }
64 
66  {
67  return mConfig;
68  }
69 
71  {
72  CopyAsConcreteConfig( mConfig, cfgObject );
73 
74  if ( !mConfig.HasSourceFile() )
75  {
76  AddConfigErrorMessage("The provided config object lacked the field 'SourceFile'");
77  return false;
78  }
79 
80  const std::string & location = mConfig.GetSourceFile();
81  if ( location == "")
82  {
83  AddConfigErrorMessage("No file selected");
84  return false;
85  }
86  mAudioFile.OpenExisting(location);
87  // Check that the given file can be opened
88  if ( ! mAudioFile.IsReadable() )
89  {
90  AddConfigErrorMessage("The audio file '" + location + "' could not be opened");
91  return false;
92  }
93 
94 
95  if ( mConfig.GetSelectedChannel() < 0
96  || mConfig.GetSelectedChannel() >= mAudioFile.GetHeader().GetChannels() )
97  {
98  AddConfigErrorMessage("The channel selected for reading does not exist");
99  return false;
100  }
101 
103  return true;
104  }
105 
107  {
108  if ( not mNativeStream )
109  mNativeStream = mAudioFile.GetStream();
110 
111  mNativeStream->PrepareReading();
112  mEOFReached = false;
113 
114  return true;
115  }
116 
118  {
120  delete mNativeStream;
122 
123  return true;
124  }
125 
127  {
128  bool result = Do( mOutput.GetAudio() );
129  mOutput.Produce();
130 
131  return result;
132  }
133 
134 
135  bool MonoAudioFileReader::Do( Audio & output )
136  {
137  TData * outputBuffer = output.GetBuffer().GetPtr();
138  const unsigned outputSize = output.GetSize();
139 
140  if (not mSeekControl.HasBeenRead())
141  {
143  mEOFReached=false;
144  }
145 
146  const unsigned long framePosition = mNativeStream->GetFramePosition();
147  const TTime secondsPosition =
148  framePosition / mAudioFile.GetHeader().GetSampleRate();
149 
150  if (not mEOFReached)
151  {
152  mEOFReached = mNativeStream->ReadData(
153  mConfig.GetSelectedChannel(), outputBuffer, outputSize);
154  }
155  else
156  {
157  memset (outputBuffer, 0, outputSize*sizeof(TData));
158  }
159  output.SetBeginTime( secondsPosition*1000 );
160  output.SetSampleRate( mAudioFile.GetHeader().GetSampleRate() );
161 
162  mTimeOutput.SendControl( secondsPosition*1000.);
163  mFramePositionOutput.SendControl( framePosition );
164  mProgressOutput.SendControl( float(framePosition)/GetHeader().GetSamples());
165 
166  if ( not mEOFReached ) return true; // Still in the middle
167  if ( not mConfig.GetLoop() ) return false; // End reached, not looping
168 
169  mNativeStream->SeekTo(0);
170  mEOFReached=false;
171  return true;
172  }
173 }
174