Nsound  0.9.4
ns_vocoder.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // $Id: ns_vocoder.cc 874 2014-09-08 02:21:29Z weegreenblobbie $
4 //
5 //-----------------------------------------------------------------------------
6 
7 #include <Nsound/NsoundAll.h>
8 
9 #include <cstdio>
10 #include <iostream>
11 #include <vector>
12 #include <string>
13 #include <sstream>
14 
15 using namespace Nsound;
16 
17 using std::cout;
18 using std::cerr;
19 using std::endl;
20 
21 //-----------------------------------------------------------------------------
22 boolean
23 file_exists(const std::string filename)
24 {
25  std::FILE * f_in;
26 
27  f_in = std::fopen(filename.c_str(), "r");
28 
29  if(f_in)
30  {
31  std::fclose(f_in);
32  return true;
33  }
34 
35  return false;
36 }
37 
38 //-----------------------------------------------------------------------------
39 void
41 {
42  cout << endl
43  << "usage: ns_vocoder OPTIONS voice_wave carrier_wave output_wave" << endl
44  << endl
45  << "Options are:" << endl
46  << endl
47  << " -h|--help Prints this message" << endl
48  << " -v|--verbose Verbose" << endl
49  << " -n|--bands N The number of frequency bands to use" << endl
50  << " -w|--window S The window duration in seconds for calculating the envelope" << endl
51  << " -m|--fmax F The maximum frequency in the filter bank" << endl
52  << endl;
53 }
54 
55 //-----------------------------------------------------------------------------
56 int
57 main(int argc, char ** argv)
58 {
59  if(argc < 3)
60  {
61  printUsage();
62  return 1;
63  }
64 
65  std::vector<std::string> args;
66 
67  for(int32 i = 1; i < argc; ++i)
68  {
69  args.push_back(argv[i]);
70  }
71 
72  float64 specific_window = 0;
73  uint32 specific_n_bands = 0;
74  float64 specific_fmax = 0;
75 
76  boolean verbose = false;
77 
78  std::vector<std::string>::iterator itor;
79  std::vector<std::string>::iterator end;
80  std::vector<std::string> files;
81 
82  for(itor = args.begin(), end = args.end();
83  itor != args.end();
84  ++itor)
85  {
86  if(*itor == "-h" || *itor == "--help")
87  {
88  printUsage();
89  }
90  else
91  if(*itor == "-m" || *itor == "--fmax")
92  {
93  std::stringstream ss(*(itor + 1));
94  ss >> specific_fmax;
95  ++itor;
96  }
97  else
98  if(*itor == "-n" || *itor == "--bands")
99  {
100  std::stringstream ss(*(itor + 1));
101  ss >> specific_n_bands;
102  ++itor;
103  }
104  else
105  if(*itor == "-w" || *itor == "--window")
106  {
107  std::stringstream ss(*(itor + 1));
108  ss >> specific_window;
109  ++itor;
110  }
111  else
112  if(*itor == "-v" || *itor == "--verbose")
113  {
114  verbose = true;
115  }
116  else
117  {
118  files.push_back(*itor);
119  }
120  }
121 
122  if(files.size() != 3)
123  {
124  cerr << "Wrong number of arguments!\n";
125  return 1;
126  }
127 
128  std::string voice_file = files[0];
129  std::string carrier_file = files[1];
130  std::string output_file = files[2];
131 
132  if(!file_exists(voice_file))
133  {
134  cerr << "ns_vocoder: can't find the file \"" << voice_file
135  << "\"" << endl;
136 
137  return 1;
138  }
139 
140  if(!file_exists(carrier_file))
141  {
142  cerr << "ns_vocoder: can't find the file \"" << voice_file
143  << "\"" << endl;
144 
145  return 1;
146  }
147 
148  AudioStream voice(voice_file);
149  voice.mono();
150  AudioStream carrier(carrier_file);
151 
152  float64 sr1 = voice.getSampleRate();
153  float64 sr2 = carrier.getSampleRate();
154  float64 sr = sr1;
155 
156  // Resample one of the signals if necessary.
157  if(sr1 != sr2)
158  {
159  if(sr1 > sr2)
160  {
161  carrier.resample2(sr1);
162  sr = sr1;
163  }
164  else
165  {
166  voice.resample2(sr2);
167  sr = sr2;
168  }
169  }
170 
171  // Setup defaults
172  float64 window = 0.020;
173  uint32 n_bands = 16;
174  float64 fmax = 4000.0;
175 
176  if(specific_window > 0)
177  {
178  window = specific_window;
179  }
180 
181  if(specific_n_bands > 0)
182  {
183  n_bands = specific_n_bands;
184  }
185 
186  if(specific_fmax > 0)
187  {
188  fmax = specific_fmax;
189  }
190 
191  if(verbose)
192  {
193  cout << "voice wav = " << voice_file << endl
194  << "carrier wav = " << carrier_file << endl
195  << "output wav = " << output_file << endl
196  << "n bands = " << n_bands << endl
197  << "window sec = " << window << endl
198  << "fmax = " << fmax << endl;
199  }
200 
201  Vocoder vocoder(sr, window, n_bands, fmax);
202 
203  AudioStream output(sr, carrier.getNChannels());
204 
205  for(uint32 i = 0; i < carrier.getNChannels(); ++i)
206  {
207  Buffer::iterator v = voice[0].begin();
208  Buffer::iterator end = voice[0].end();
209 
210  // Using a circulator iterator incase the carrier isn't the same length as the
211  // voice signal.
212  Buffer::circular_iterator c = carrier[i].cbegin();
213 
214  Buffer temp;
215 
216  while(v != end)
217  {
218  temp << vocoder.filter(*v, *c);
219  ++v;
220  ++c;
221  }
222 
223  output[i] = temp;
224 
225  vocoder.reset();
226  }
227 
228  output.normalize();
229 
230  output *= 0.666;
231 
232  output >> output_file.c_str();
233 
234  return 0;
235 }
unsigned int uint32
Definition: Nsound.h:153
float64 getSampleRate() const
Returns the sample rate of the stream.
Definition: AudioStream.h:217
A circulator iterator for class Buffer.
boolean file_exists(const std::string filename)
Definition: ns_vocoder.cc:23
double float64
Definition: Nsound.h:146
uint32 getNChannels(void) const
Returns the number of audio channels in the stream.
Definition: AudioStream.h:212
void mono()
Collapses all channels into one Buffer making it mono.
Definition: AudioStream.cc:258
void reset()
Definition: Vocoder.cc:286
void resample2(float64 new_sample_rate)
Resample to the specified sample rate.
Definition: AudioStream.cc:720
int main(int argc, char **argv)
Definition: ns_vocoder.cc:57
A Buffer for storing audio samples.
Definition: Buffer.h:60
signed int int32
Definition: Nsound.h:142
FloatVector::iterator iterator
Definition: Buffer.h:69
void printUsage()
Definition: ns_vocoder.cc:40
Buffer filter(const Buffer &voice, const Buffer &carrier)
Definition: Vocoder.cc:234
float64 sr
Definition: example3.cc:24