30#if JUCE_USE_LAME_AUDIO_FORMAT
32class LAMEEncoderAudioFormat::Writer :
public AudioFormatWriter
35 Writer (OutputStream* destStream,
const String& formatName,
36 const File& appFile,
int vbr,
int cbr,
37 double sampleRate,
unsigned int numberOfChannels,
38 int bitsPerSample,
const StringPairArray& metadata)
39 : AudioFormatWriter (destStream, formatName, sampleRate,
40 numberOfChannels, (unsigned int) bitsPerSample),
41 vbrLevel (vbr), cbrBitrate (cbr)
43 WavAudioFormat wavFormat;
45 if (
auto* out = tempWav.getFile().createOutputStream())
47 writer.reset (wavFormat.createWriterFor (out, sampleRate, numChannels,
48 bitsPerSample, metadata, 0));
50 args.add (appFile.getFullPathName());
56 args.add (
"--vbr-new");
58 args.add (String (vbrLevel));
64 args.add (String (cbrBitrate));
67 addMetadataArg (metadata,
"id3title",
"--tt");
68 addMetadataArg (metadata,
"id3artist",
"--ta");
69 addMetadataArg (metadata,
"id3album",
"--tl");
70 addMetadataArg (metadata,
"id3comment",
"--tc");
71 addMetadataArg (metadata,
"id3date",
"--ty");
72 addMetadataArg (metadata,
"id3genre",
"--tg");
73 addMetadataArg (metadata,
"id3trackNumber",
"--tn");
77 void addMetadataArg (
const StringPairArray& metadata,
const char* key,
const char* lameFlag)
79 auto value = metadata.getValue (key, {});
81 if (value.isNotEmpty())
90 if (writer !=
nullptr)
99 bool write (
const int** samplesToWrite,
int numSamples)
101 return writer !=
nullptr && writer->write (samplesToWrite, numSamples);
105 int vbrLevel, cbrBitrate;
106 TemporaryFile tempWav {
".wav" };
107 std::unique_ptr<AudioFormatWriter> writer;
110 bool runLameChildProcess (
const TemporaryFile& tempMP3,
const StringArray& processArgs)
const
114 if (cp.start (processArgs))
116 auto childOutput = cp.readAllProcessOutput();
117 DBG (childOutput); ignoreUnused (childOutput);
119 cp.waitForProcessToFinish (10000);
120 return tempMP3.getFile().getSize() > 0;
126 bool convertToMP3()
const
128 TemporaryFile tempMP3 (
".mp3");
130 StringArray args2 (args);
131 args2.add (tempWav.getFile().getFullPathName());
132 args2.add (tempMP3.getFile().getFullPathName());
134 DBG (args2.joinIntoString (
" "));
136 if (runLameChildProcess (tempMP3, args2))
138 FileInputStream fis (tempMP3.getFile());
140 if (fis.openedOk() && output->writeFromInputStream (fis, -1) > 0)
150 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Writer)
154LAMEEncoderAudioFormat::LAMEEncoderAudioFormat (
const File& lameApplication)
155 : AudioFormat (
"MP3 file",
".mp3"),
156 lameApp (lameApplication)
160LAMEEncoderAudioFormat::~LAMEEncoderAudioFormat()
164bool LAMEEncoderAudioFormat::canHandleFile (
const File&)
169Array<int> LAMEEncoderAudioFormat::getPossibleSampleRates()
171 return { 32000, 44100, 48000 };
174Array<int> LAMEEncoderAudioFormat::getPossibleBitDepths()
179bool LAMEEncoderAudioFormat::canDoStereo() {
return true; }
180bool LAMEEncoderAudioFormat::canDoMono() {
return true; }
181bool LAMEEncoderAudioFormat::isCompressed() {
return true; }
183StringArray LAMEEncoderAudioFormat::getQualityOptions()
185 static const char* vbrOptions[] = {
"VBR quality 0 (best)",
"VBR quality 1",
"VBR quality 2",
"VBR quality 3",
186 "VBR quality 4 (normal)",
"VBR quality 5",
"VBR quality 6",
"VBR quality 7",
187 "VBR quality 8",
"VBR quality 9 (smallest)",
nullptr };
188 StringArray opts (vbrOptions);
190 const int cbrRates[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
192 for (
int i = 0; i < numElementsInArray (cbrRates); ++i)
193 opts.add (String (cbrRates[i]) +
" Kb/s CBR");
198AudioFormatReader* LAMEEncoderAudioFormat::createReaderFor (InputStream*,
const bool)
203AudioFormatWriter* LAMEEncoderAudioFormat::createWriterFor (OutputStream* streamToWriteTo,
204 double sampleRateToUse,
205 unsigned int numberOfChannels,
207 const StringPairArray& metadataValues,
208 int qualityOptionIndex)
210 if (streamToWriteTo ==
nullptr)
216 const String qual (getQualityOptions() [qualityOptionIndex]);
218 if (qual.contains (
"VBR"))
219 vbr = qual.retainCharacters (
"0123456789").getIntValue();
221 cbr = qual.getIntValue();
223 return new Writer (streamToWriteTo, getFormatName(), lameApp, vbr, cbr,
224 sampleRateToUse, numberOfChannels, bitsPerSample, metadataValues);