pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_AudioFileWriter.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004   by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #ifndef PLONK_AUDIOFILEWRITER_H
00040 #define PLONK_AUDIOFILEWRITER_H
00041 
00042 #include "../../core/plonk_CoreForwardDeclarations.h"
00043 #include "../plonk_FilesForwardDeclarations.h"
00044 #include "../../core/plonk_SmartPointer.h"
00045 #include "../../core/plonk_WeakPointer.h"
00046 #include "../../core/plonk_SmartPointerContainer.h"
00047 #include "../../containers/plonk_Text.h"
00048 #include "plonk_AudioFile.h"
00049 #include "plonk_AudioFileMetaData.h"
00050 
00051 
00052 template<class SampleType>
00053 class AudioFileWriterInternalBase : public SmartPointer
00054 {
00055 private:
00056     AudioFileWriterInternalBase(); // incompatible SampleType
00057 };
00058 
00059 template<> class AudioFileWriterInternalBase<Char>    : public SmartPointer { public: AudioFileWriterInternalBase<Char>()   : isFloat (false) { } protected: const bool isFloat; };
00060 template<> class AudioFileWriterInternalBase<Short>   : public SmartPointer { public: AudioFileWriterInternalBase<Short>()  : isFloat (false) { } protected: const bool isFloat; };
00061 template<> class AudioFileWriterInternalBase<Int24>   : public SmartPointer { public: AudioFileWriterInternalBase<Int24>()  : isFloat (false) { } protected: const bool isFloat; };
00062 template<> class AudioFileWriterInternalBase<Int>     : public SmartPointer { public: AudioFileWriterInternalBase<Int>()    : isFloat (false) { } protected: const bool isFloat; };
00063 template<> class AudioFileWriterInternalBase<Float>   : public SmartPointer { public: AudioFileWriterInternalBase<Float>()  : isFloat (true)  { } protected: const bool isFloat; };
00064 template<> class AudioFileWriterInternalBase<Double>  : public SmartPointer { public: AudioFileWriterInternalBase<Double>() : isFloat (true)  { } protected: const bool isFloat; };
00065 
00066 template<class SampleType>
00067 class AudioFileWriterInternal : public AudioFileWriterInternalBase<SampleType>
00068 {
00069 public:
00070     typedef NumericalArray<SampleType>  Buffer;
00071     
00072     AudioFileWriterInternal (const int bufferSize) throw()
00073     :   buffer (Buffer::withSize (bufferSize > 0 ? bufferSize : AudioFile::DefaultBufferSize, false)),
00074         ready (false)
00075     {
00076         pl_AudioFileWriter_Init (&peer);
00077     }
00078     
00079     bool openPath (FilePath const& path)
00080     {
00081         return pl_AudioFileWriter_Open (&peer, path.fullpath().getArray()) == PlankResult_OK;
00082     }
00083     
00084     bool openFile (PlankFileRef file)
00085     {
00086         return pl_AudioFileWriter_OpenWithFile (&peer, file) == PlankResult_OK;
00087     }
00088     
00089     bool initBytes (PlankFileRef file, ByteArray const& bytes) throw()
00090     {
00091         return BinaryFileInternal::setupBytes (file, bytes, true);
00092     }
00093     
00094     static AudioFileWriterInternal* createPCM (FilePath const& path, const ChannelLayout channelLayout, const double sampleRate, const int bufferSize) throw()
00095     {
00096         AudioFileWriterInternal* internal = new AudioFileWriterInternal ((channelLayout.getValue() & 0x0000FFFF) * bufferSize);
00097         const Text ext = path.extension();
00098         
00099         AudioFile::Format format = AudioFile::FormatInvalid;
00100         
00101         if (ext.equalsIgnoreCase ("wav"))
00102         {
00103             format = AudioFile::FormatWAV;
00104         }
00105         else if (ext.equalsIgnoreCase ("aif"))
00106         {
00107             format = AudioFile::FormatAIFF;
00108         }
00109         else if (ext.equalsIgnoreCase ("aiff") || ext.equalsIgnoreCase ("aifc"))
00110         {
00111             format = AudioFile::FormatAIFC;
00112         }
00113         else if (ext.equalsIgnoreCase ("caf"))
00114         {
00115             format = AudioFile::FormatCAF;
00116         }
00117         else if (ext.equalsIgnoreCase ("w64"))
00118         {
00119             format = AudioFile::FormatW64;
00120         }
00121             
00122         if (!internal->initPCM (format, channelLayout, sampleRate, bufferSize))
00123         {
00124             pl_AudioFileWriter_Init (&internal->peer);
00125             goto exit;
00126         }
00127         
00128         if (!internal->openPath (path))
00129         {
00130             pl_AudioFileWriter_Close (&internal->peer);
00131             pl_AudioFileWriter_Init (&internal->peer);
00132             goto exit;
00133         }
00134         
00135         internal->ready = true;
00136         
00137     exit:
00138         return internal;
00139     }
00140 
00141     static AudioFileWriterInternal* createPCM (ByteArray const& bytes, AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate, const int bufferSize) throw()
00142     {
00143         AudioFileWriterInternal* internal = new AudioFileWriterInternal ((channelLayout & 0x0000FFFF) * bufferSize);
00144         PlankFile file;
00145         
00146         if (!internal->initBytes (&file, bytes))
00147         {
00148             pl_AudioFileWriter_Init (&internal->peer);
00149             goto exit;
00150         }
00151         
00152         if (!internal->initPCM (format, channelLayout, sampleRate, bufferSize))
00153         {
00154             pl_AudioFileWriter_Init (&internal->peer);
00155             goto exit;
00156         }
00157         
00158         if (!internal->openFile (&file))
00159         {
00160             pl_AudioFileWriter_Close (&internal->peer);
00161             pl_AudioFileWriter_Init (&internal->peer);
00162             goto exit;
00163         }
00164         
00165         internal->ready = true;
00166         
00167     exit:
00168         return internal;
00169     }
00170     
00171     static AudioFileWriterInternal* createCompressedVBR (FilePath const& path, const ChannelLayout channelLayout, const double sampleRate,
00172                                                          const float quality, const double frameDuration, const int bufferSize) throw()
00173     {
00174         AudioFileWriterInternal* internal = new AudioFileWriterInternal ((channelLayout.getValue() & 0x0000FFFF) * bufferSize);
00175         const Text ext = path.extension();
00176 
00177         AudioFile::Format format = AudioFile::FormatInvalid;
00178         
00179         if (false)
00180         {
00181         }
00182 #if PLANK_OGGVORBIS
00183         else if (ext.equalsIgnoreCase ("ogg") &&
00184                  (sizeof (SampleType) == 4) &&
00185                  internal->isFloat)
00186         {
00187             format = AudioFile::FormatOggVorbis;
00188         }
00189 #endif
00190 #if PLANK_OPUS
00191         else if (ext.equalsIgnoreCase ("opus") &&
00192                  (sizeof (SampleType) == 4) &&
00193                  internal->isFloat)
00194         {
00195             format = AudioFile::FormatOpus;
00196         }
00197 #endif
00198         
00199         if (!internal->initCompressedVBR (format, channelLayout, sampleRate, quality, frameDuration, bufferSize))
00200         {
00201             pl_AudioFileWriter_Init (&internal->peer);
00202             goto exit;
00203         }
00204         
00205         if (!internal->openPath (path))
00206         {
00207             pl_AudioFileWriter_Close (&internal->peer);
00208             pl_AudioFileWriter_Init (&internal->peer);
00209             goto exit;
00210         }
00211         
00212         internal->ready = true;
00213         
00214     exit:
00215         return internal;
00216     }
00217     
00218     static AudioFileWriterInternal* createCompressedVBR (ByteArray const& bytes, AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00219                                                          const float quality, const double frameDuration, const int bufferSize) throw()
00220     {
00221         AudioFileWriterInternal* internal = new AudioFileWriterInternal ((channelLayout.getValue() & 0x0000FFFF) * bufferSize);
00222         PlankFile file;
00223         
00224         if (!internal->initBytes (&file, bytes))
00225         {
00226             pl_AudioFileWriter_Init (&internal->peer);
00227             goto exit;
00228         }
00229         
00230         if (!internal->initCompressedVBR (format, channelLayout, sampleRate, quality, frameDuration, bufferSize))
00231         {
00232             pl_AudioFileWriter_Init (&internal->peer);
00233             goto exit;
00234         }
00235         
00236         if (!internal->openFile (&file))
00237         {
00238             pl_AudioFileWriter_Close (&internal->peer);
00239             pl_AudioFileWriter_Init (&internal->peer);
00240             goto exit;
00241         }
00242         
00243         internal->ready = true;
00244         
00245     exit:
00246         return internal;
00247     }
00248     
00249     static AudioFileWriterInternal* createCompressedManaged (FilePath const& path, const ChannelLayout channelLayout, const double sampleRate,
00250                                                              const int minBitRate, const int nominalBitRate, const int maxBitRate,
00251                                                              const double frameDuration, const int bufferSize) throw()
00252     {
00253         AudioFileWriterInternal* internal = new AudioFileWriterInternal ((channelLayout.getValue() & 0x0000FFFF) * bufferSize);
00254         const Text ext = path.extension();
00255 
00256         AudioFile::Format format = AudioFile::FormatInvalid;
00257         
00258         if (false)
00259         {
00260         }
00261 #if PLANK_OGGVORBIS
00262         else if (ext.equalsIgnoreCase ("ogg") &&
00263                  (sizeof (SampleType) == 4) &&
00264                  internal->isFloat)
00265         {
00266             format = AudioFile::FormatOggVorbis;
00267         }
00268 #endif
00269 #if PLANK_OPUS
00270         else if (ext.equalsIgnoreCase ("opus") &&
00271                  (sizeof (SampleType) == 4) &&
00272                  internal->isFloat)
00273         {
00274             format = AudioFile::FormatOpus;
00275         }
00276 #endif
00277 
00278         if (!internal->initCompressedManaged (format, channelLayout, sampleRate, minBitRate, nominalBitRate, maxBitRate, frameDuration, bufferSize))
00279         {
00280             pl_AudioFileWriter_Init (&internal->peer);
00281             goto exit;
00282         }
00283         
00284         if (!internal->openPath (path))
00285         {
00286             pl_AudioFileWriter_Close (&internal->peer);
00287             pl_AudioFileWriter_Init (&internal->peer);
00288             goto exit;
00289         }
00290         
00291         internal->ready = true;
00292         
00293     exit:
00294         return internal;
00295     }
00296     
00297     static AudioFileWriterInternal* createCompressedManaged (ByteArray const& bytes, AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00298                                                              const int minBitRate, const int nominalBitRate, const int maxBitRate,
00299                                                              const double frameDuration, const int bufferSize) throw()
00300     {
00301         AudioFileWriterInternal* internal = new AudioFileWriterInternal ((channelLayout.getValue() & 0x0000FFFF) * bufferSize);
00302         PlankFile file;
00303         
00304         if (!internal->initBytes (&file, bytes))
00305         {
00306             pl_AudioFileWriter_Init (&internal->peer);
00307             goto exit;
00308         }
00309         
00310         if (!internal->initCompressedManaged (format, channelLayout, sampleRate, minBitRate, nominalBitRate, maxBitRate, frameDuration, bufferSize))
00311         {
00312             pl_AudioFileWriter_Init (&internal->peer);
00313             goto exit;
00314         }
00315         
00316         if (!internal->openFile (&file))
00317         {
00318             pl_AudioFileWriter_Close (&internal->peer);
00319             pl_AudioFileWriter_Init (&internal->peer);
00320             goto exit;
00321         }
00322         
00323         internal->ready = true;
00324         
00325     exit:
00326         return internal;
00327     }
00328 
00329     
00330     bool initPCM (const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate, const int bufferSize) throw()
00331     {
00332         ResultCode result = PlankResult_UnknownError;
00333         
00334         if (format == AudioFile::FormatWAV)
00335         {
00336             if ((result = pl_AudioFileWriter_SetFormatWAV (&peer, sizeof (SampleType) * 8, channelLayout, sampleRate, this->isFloat)) != PlankResult_OK) goto exit;
00337         }
00338         else if (format == AudioFile::FormatAIFF)
00339         {
00340             // ideally we'd allow aiff but this is used to identify aifc (below)
00341 
00342             if (this->isFloat)
00343             {
00344                 if ((result = pl_AudioFileWriter_SetFormatAIFC (&peer, sizeof (SampleType) * 8, channelLayout, sampleRate, true, false)) != PlankResult_OK) goto exit;;
00345             }
00346             else
00347             {
00348                 if ((result = pl_AudioFileWriter_SetFormatAIFF (&peer, sizeof (SampleType) * 8, channelLayout, sampleRate)) != PlankResult_OK) goto exit;;
00349             }
00350         }
00351         else if (format == AudioFile::FormatAIFC)
00352         {
00353             // ideally we'd use aifc only but some audio apps don't recognise this
00354 #if PLANK_LITTLEENDIAN
00355             if ((result = pl_AudioFileWriter_SetFormatAIFC (&peer, sizeof (SampleType) * 8, channelLayout, sampleRate, this->isFloat, !this->isFloat && sizeof (SampleType) == 2)) != PlankResult_OK) goto exit;;
00356 #endif
00357 #if PLANK_BIGENDIAN
00358             if ((result = pl_AudioFileWriter_SetFormatAIFC (&peer, sizeof (SampleType) * 8, channelLayout, sampleRate, this->isFloat, false)) != PlankResult_OK) goto exit;;
00359 #endif
00360         }
00361         else if (format == AudioFile::FormatCAF)
00362         {
00363             if ((result = pl_AudioFileWriter_SetFormatCAF (&peer, sizeof (SampleType) * 8, channelLayout, sampleRate, this->isFloat, PLANK_LITTLEENDIAN)) != PlankResult_OK) goto exit;
00364             this->setHeaderPad (AudioFile::CAFDefaultHeaderPad);
00365         }
00366         else if (format == AudioFile::FormatW64)
00367         {
00368             if ((result = pl_AudioFileWriter_SetFormatW64 (&peer, sizeof (SampleType) * 8, channelLayout, sampleRate, this->isFloat)) != PlankResult_OK) goto exit;;
00369         }
00370       
00371     exit:
00372         return result == PlankResult_OK;
00373     }
00374     
00375     bool initCompressedVBR (const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate, const float quality,
00376                             const double frameDuration, const int bufferSize) throw()
00377     {
00378         ResultCode result = PlankResult_UnknownError;
00379                 
00380         if (false)
00381         {
00382         }
00383 #if PLANK_OGGVORBIS
00384         else if (format == AudioFile::FormatOggVorbis)
00385         {
00386             if ((result = pl_AudioFileWriter_SetFormatOggVorbis (&peer, quality, channelLayout, sampleRate)) != PlankResult_OK) goto exit;;
00387         }
00388 #endif
00389 #if PLANK_OPUS
00390         else if (format == AudioFile::FormatOpus)
00391         {
00392             if ((result = pl_AudioFileWriter_SetFormatOpus (&peer, quality, channelLayout, sampleRate, frameDuration <= 0.0 ? 0.02 : frameDuration)) != PlankResult_OK) goto exit;;
00393         }
00394 #endif
00395         
00396     exit:
00397         return result == PlankResult_OK;
00398     }
00399     
00400     bool initCompressedManaged (const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00401                                 const int minBitRate, const int nominalBitRate, const int maxBitRate,
00402                                 const double frameDuration, const int bufferSize) throw()
00403     {
00404         ResultCode result = PlankResult_UnknownError;
00405             
00406         if (false)
00407         {
00408         }
00409 #if PLANK_OGGVORBIS
00410         else if (format == AudioFile::FormatOggVorbis)
00411         {
00412             if ((result = pl_AudioFileWriter_SetFormatOggVorbisManaged (&peer,
00413                                                                         minBitRate, nominalBitRate, maxBitRate,
00414                                                                         channelLayout, sampleRate)) != PlankResult_OK) goto exit;;
00415         }
00416 #endif
00417 #if PLANK_OPUS
00418         else if (format == AudioFile::FormatOpus)
00419         {
00420             if ((result = pl_AudioFileWriter_SetFormatOpusManaged (&peer,
00421                                                                    nominalBitRate == 0 ? (maxBitRate + minBitRate) / 2 : nominalBitRate,
00422                                                                    channelLayout, sampleRate, frameDuration <= 0.0 ? 0.02 : frameDuration)) != PlankResult_OK) goto exit;;
00423         }
00424 #endif
00425         
00426     exit:
00427         return result == PlankResult_OK;
00428     }
00429     
00430     ~AudioFileWriterInternal()
00431     {
00432         PlankResult result = PlankResult_OK;
00433         result = pl_AudioFileWriter_DeInit (&peer);
00434         plonk_assert (result == PlankResult_OK);
00435     }
00436     
00437     void setHeaderPad (const UnsignedInt bytes) throw()
00438     {
00439         pl_AudioFileWriter_SetHeaderPad (&peer, bytes);
00440     }
00441     
00442     void writeHeader() throw()
00443     {
00444         pl_AudioFileWriter_WriteHeader (&peer);
00445     }
00446     
00447     void close() throw()
00448     {
00449         pl_AudioFileWriter_Close (&peer);
00450     }
00451     
00452     bool writeFrames (const int numFrames, const SampleType* frameData) throw()
00453     {
00454         return pl_AudioFileWriter_WriteFrames (&peer, true, numFrames, frameData) == PlankResult_OK;
00455     }
00456     
00457     bool writeFrames (Buffer const& frames) throw()
00458     {
00459         const int numChannels = pl_AudioFileFormatInfo_GetNumChannels (&peer.formatInfo);
00460         plonk_assert ((frames.length() % numChannels) == 0);
00461         return pl_AudioFileWriter_WriteFrames (&peer, true, frames.length() / numChannels, frames.getArray()) == PlankResult_OK;
00462     }
00463     
00464     template<class OtherType>
00465     bool writeFrames (NumericalArray<OtherType> const& frames) throw()
00466     {
00467         bool success = true;
00468         const int numChannels = pl_AudioFileFormatInfo_GetNumChannels (&peer.formatInfo);
00469         
00470         plonk_assert ((frames.length() % numChannels) == 0);
00471         
00472         SampleType* const nativeSamples = buffer.getArray();
00473         const OtherType* sourceSamples = frames.getArray();
00474         const int nativeSamplesLength = buffer.length();
00475         
00476         int numSamplesRemainaing = frames.length();
00477         
00478         while (numSamplesRemainaing > 0)
00479         {
00480             const int numSamplesThisTime = plonk::min (nativeSamplesLength, numSamplesRemainaing);
00481             NumericalArrayConverter<SampleType, OtherType>::convertScaled (nativeSamples, sourceSamples, numSamplesThisTime);
00482             success = pl_AudioFileWriter_WriteFrames (&peer, true, numSamplesThisTime / numChannels, nativeSamples) == PlankResult_OK;
00483             
00484             if (!success) break;
00485             
00486             numSamplesRemainaing -= numSamplesThisTime;
00487             sourceSamples += numSamplesThisTime;
00488         }
00489         
00490         return success;
00491     }
00492     
00493     bool writeFrames (AudioFileReader& reader, const int numFrames) throw()
00494     {
00495         const int numChannels = pl_AudioFileFormatInfo_GetNumChannels (&peer.formatInfo);
00496 //        plonk_assert (peer.formatInfo.sampleRate == reader.getSampleRate());
00497         plonk_assert (numChannels == reader.getNumChannels());
00498         
00499         const int bufferLength = buffer.length();
00500 //        const int bufferFrames = bufferLength / numChannels;
00501         int framesRead;
00502                 
00503         if (numFrames <= 0)
00504         {
00505             do
00506             {
00507                 reader.readFrames (buffer);
00508                 framesRead = buffer.length() / numChannels;
00509                             
00510                 if (framesRead == 0) break;
00511                 
00512                 this->writeFrames (buffer);
00513             }
00514             while (!reader.didHitEOF());
00515         }
00516         else
00517         {
00518             int numFramesRemaining = numFrames;
00519             
00520             do
00521             {
00522                 buffer.setSize (plonk::min (numFramesRemaining * numChannels, bufferLength), false);
00523                 reader.readFrames (buffer);
00524                 framesRead = buffer.length() / numChannels;
00525                 
00526                 if (framesRead == 0) break;
00527                 
00528                 numFramesRemaining -= framesRead;
00529                 this->writeFrames (buffer);
00530             }
00531             while ((numFramesRemaining > 0) && !reader.didHitEOF());
00532         }
00533         
00534         // and reset for next time
00535         buffer.setSize (bufferLength, false);
00536         
00537         return true;
00538     }
00539     
00540     AudioFileMetaData getMetaData() const throw()
00541     {
00542         return AudioFileMetaData (pl_AudioFileWriter_GetMetaData (const_cast<PlankAudioFileWriter*> (&peer)));
00543     }
00544 
00545     void setMetaData (AudioFileMetaData const& metaData) throw()
00546     {
00547         AudioFileMetaData m (metaData);
00548         pl_AudioFileWriter_SetMetaData (&peer, m.incrementRefCountAndGetPeer());
00549     }
00550     
00551     friend class AudioFileWriter<SampleType>;
00552     
00553 private:
00554     PlankAudioFileWriter peer;
00555     Buffer buffer;
00556     bool ready;
00557 };
00558 
00559 
00566 template<class SampleType>
00567 class AudioFileWriter: public SmartPointerContainer< AudioFileWriterInternal<SampleType> >
00568 {
00569 public:
00570     typedef AudioFileWriterInternal<SampleType> Internal;
00571     typedef SmartPointerContainer<Internal>     Base;
00572     typedef NumericalArray<SampleType>          Buffer;
00573 
00574     AudioFileWriter (const int bufferSize = AudioFile::DefaultBufferSize) throw()
00575     :   Base (new Internal (bufferSize))
00576     {
00577     }
00578     
00579     AudioFileWriter (FilePath const& path, const ChannelLayout channelLayout, const double sampleRate,
00580                      const int bufferSize = AudioFile::DefaultBufferSize) throw()
00581         :       Base (Internal::createPCM (path, channelLayout, sampleRate, bufferSize))
00582         {
00583         }
00584     
00585     AudioFileWriter (FilePath const& path, const ChannelLayout channelLayout, const double sampleRate,
00586                      const float quality,
00587                      const double frameDuration = 0.0, const int bufferSize = AudioFile::DefaultBufferSize) throw()
00588         :       Base (Internal::createCompressedVBR (path, channelLayout, sampleRate, quality, frameDuration, bufferSize))
00589         {
00590         }
00591     
00592     AudioFileWriter (FilePath const& path, const ChannelLayout channelLayout, const double sampleRate,
00593                      const int minBitRate, const int nominalBitRate, const int maxBitRate,
00594                      const double frameDuration = 0.0, const int bufferSize = AudioFile::DefaultBufferSize) throw()
00595         :       Base (Internal::createCompressedManaged (path, channelLayout, sampleRate, minBitRate, nominalBitRate, maxBitRate, frameDuration, bufferSize))
00596         {
00597         }
00598     
00599     AudioFileWriter (ByteArray const& bytes, const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00600                      const int bufferSize = AudioFile::DefaultBufferSize) throw()
00601         :       Base (Internal::createPCM (bytes, format, channelLayout, sampleRate, bufferSize))
00602         {
00603         }
00604     
00605     AudioFileWriter (ByteArray const& bytes, const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00606                      const float quality,
00607                      const double frameDuration = 0.0, const int bufferSize = AudioFile::DefaultBufferSize) throw()
00608         :       Base (Internal::createCompressedVBR (bytes, format, channelLayout, sampleRate, quality, frameDuration, bufferSize))
00609         {
00610         }
00611 
00612     AudioFileWriter (ByteArray const& bytes, const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00613                      const int minBitRate, const int nominalBitRate, const int maxBitRate,
00614                      const double frameDuration = 0.0, const int bufferSize = AudioFile::DefaultBufferSize) throw()
00615         :       Base (Internal::createCompressedManaged (bytes, format, channelLayout, sampleRate, minBitRate, nominalBitRate, maxBitRate, frameDuration, bufferSize))
00616         {
00617         }
00618     
00619     bool initPCM (const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00620                   const int bufferSize = AudioFile::DefaultBufferSize) throw()
00621         {
00622         return this->getInternal()->initPCM (format, channelLayout, sampleRate, bufferSize);
00623         }
00624     
00625     bool initCompressedVBR (const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00626                             const float quality,
00627                             const double frameDuration = 0.0, const int bufferSize = AudioFile::DefaultBufferSize) throw()
00628         {
00629         return this->getInternal()->initCompressedVBR (format, channelLayout, sampleRate, quality, frameDuration, bufferSize);
00630         }
00631     
00632     bool initCompressedManaged (const AudioFile::Format format, const ChannelLayout channelLayout, const double sampleRate,
00633                                 const int minBitRate, const int nominalBitRate, const int maxBitRate,
00634                                 const double frameDuration = 0.0, const int bufferSize = AudioFile::DefaultBufferSize) throw()
00635         {
00636         return this->getInternal()->initCompressedManaged (format, channelLayout, sampleRate, minBitRate, nominalBitRate, maxBitRate, frameDuration, bufferSize);
00637         }
00638     
00639     bool openPath (FilePath const& path) throw()
00640     {
00641         bool result = this->getInternal()->openPath (path);
00642         this->getInternal()->ready = result;
00643         return result;
00644     }
00645     
00646     bool openBytes (ByteArray const& bytes) throw()
00647     {
00648         bool result = this->getInternal()->openBytes (bytes);
00649         this->getInternal()->ready = result;
00650         return result;
00651     }
00652     
00653     void setHeaderPad (const UnsignedInt bytes) throw()
00654     {
00655         this->getInternal()->setHeaderPad (bytes);
00656     }
00657     
00658     void writeHeader() throw()
00659     {
00660         this->getInternal()->writeHeader();
00661     }
00662     
00663     void close() throw()
00664     {
00665         this->getInternal()->close();
00666     }
00667 
00668     bool isReady() const throw()
00669     {
00670         return this->getInternal()->ready;
00671     }
00672 
00674     inline int getNumChannels() const throw()
00675     {
00676         return pl_AudioFileWriter_GetNumChannels (&this->getInternal()->peer);
00677     }
00678     
00679     inline ChannelLayout getChannelLayout() const throw()
00680     {
00681         PlankChannelLayout layout;
00682         pl_AudioFileWriter_GetChannelLayout (&this->getInternal()->peer, &layout);
00683         return layout;
00684     }
00685     
00686     inline ChannelIdentifier getChannelIdentifier (const int channel) const throw()
00687     {
00688         PlankChannelIdentifier identifier;
00689         pl_AudioFileWriter_GetChannelItentifier (&this->getInternal()->peer, channel, &identifier);
00690         return identifier;
00691     }
00692     
00693     inline void setChannelIdentifier (const int channel, ChannelIdentifier const& identifier) const throw()
00694     {
00695         pl_AudioFileWriter_SetChannelItentifier (&this->getInternal()->peer, channel, identifier);
00696     }
00697     
00699     inline double getSampleRate() const throw()
00700     {
00701         return this->getInternal()->peer.formatInfo.sampleRate;
00702     }
00703     
00704     bool writeFrames (const int numFrames, const SampleType* frameData) throw()
00705     {
00706         return this->getInternal()->writeFrames (numFrames, frameData);
00707     }
00708 
00709     bool writeFrames (Buffer const& frames) throw()
00710     {
00711         return this->getInternal()->writeFrames (frames);
00712     }
00713     
00714     bool writeFrames (AudioFileReader& reader, const int numFrames = 0) throw()
00715     {
00716         return this->getInternal()->writeFrames (reader, numFrames);
00717     }
00718     
00719     template<class OtherType>
00720     bool writeFrames (NumericalArray<OtherType> const& frames) throw()
00721     {
00722         return this->getInternal()->writeFrames (frames);
00723     }
00724     
00725     AudioFileMetaData getMetaData() const throw()
00726     {
00727         return this->getInternal()->getMetaData();
00728     }
00729     
00730     void setMetaData (AudioFileMetaData const& metaData) throw()
00731     {
00732         return this->getInternal()->setMetaData (metaData);
00733     }
00734 
00735 };
00736 
00737 #endif // PLONK_AUDIOFILEWRITER_H
 All Classes Functions Typedefs Enumerations Enumerator Properties