Merged changes in the trunk up to revision 54992.
[blender.git] / intern / audaspace / sndfile / AUD_SndFileWriter.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * Copyright 2009-2011 Jörg Hermann Müller
5  *
6  * This file is part of AudaSpace.
7  *
8  * Audaspace is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * AudaSpace is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Audaspace; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file audaspace/sndfile/AUD_SndFileWriter.cpp
26  *  \ingroup audsndfile
27  */
28
29
30 #include "AUD_SndFileWriter.h"
31
32 #include <cstring>
33
34 static const char* fileopen_error = "AUD_SndFileWriter: File couldn't be written.";
35 static const char* format_error = "AUD_SndFileWriter: Unsupported format.";
36
37 AUD_SndFileWriter::AUD_SndFileWriter(std::string filename, AUD_DeviceSpecs specs,
38                                                                          AUD_Container format, AUD_Codec codec, unsigned int bitrate) :
39         m_specs(specs)
40 {
41         SF_INFO sfinfo;
42
43         sfinfo.channels = specs.channels;
44         sfinfo.samplerate = int(specs.rate);
45
46         switch(format)
47         {
48         case AUD_CONTAINER_FLAC:
49                 sfinfo.format = SF_FORMAT_FLAC;
50                 switch(specs.format)
51                 {
52                 case AUD_FORMAT_S16:
53                         sfinfo.format |= SF_FORMAT_PCM_16;
54                         break;
55                 case AUD_FORMAT_S24:
56                         sfinfo.format |= SF_FORMAT_PCM_24;
57                         break;
58                 case AUD_FORMAT_S32:
59                         sfinfo.format |= SF_FORMAT_PCM_32;
60                         break;
61                 case AUD_FORMAT_FLOAT32:
62                         sfinfo.format |= SF_FORMAT_FLOAT;
63                         break;
64                 case AUD_FORMAT_FLOAT64:
65                         sfinfo.format |= SF_FORMAT_DOUBLE;
66                         break;
67                 default:
68                         sfinfo.format = 0;
69                         break;
70                 }
71                 break;
72         case AUD_CONTAINER_OGG:
73                 if(codec == AUD_CODEC_VORBIS)
74                         sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
75                 else
76                         sfinfo.format = 0;
77                 break;
78         case AUD_CONTAINER_WAV:
79                 sfinfo.format = SF_FORMAT_WAV;
80                 switch(specs.format)
81                 {
82                 case AUD_FORMAT_U8:
83                         sfinfo.format |= SF_FORMAT_PCM_U8;
84                         break;
85                 case AUD_FORMAT_S16:
86                         sfinfo.format |= SF_FORMAT_PCM_16;
87                         break;
88                 case AUD_FORMAT_S24:
89                         sfinfo.format |= SF_FORMAT_PCM_24;
90                         break;
91                 case AUD_FORMAT_S32:
92                         sfinfo.format |= SF_FORMAT_PCM_32;
93                         break;
94                 case AUD_FORMAT_FLOAT32:
95                         sfinfo.format |= SF_FORMAT_FLOAT;
96                         break;
97                 case AUD_FORMAT_FLOAT64:
98                         sfinfo.format |= SF_FORMAT_DOUBLE;
99                         break;
100                 default:
101                         sfinfo.format = 0;
102                         break;
103                 }
104                 break;
105         default:
106                 sfinfo.format = 0;
107                 break;
108         }
109
110         if(sfinfo.format == 0)
111                 AUD_THROW(AUD_ERROR_SPECS, format_error);
112
113         m_sndfile = sf_open(filename.c_str(), SFM_WRITE, &sfinfo);
114
115         if(!m_sndfile)
116                 AUD_THROW(AUD_ERROR_FILE, fileopen_error);
117 }
118
119 AUD_SndFileWriter::~AUD_SndFileWriter()
120 {
121         sf_close(m_sndfile);
122 }
123
124 int AUD_SndFileWriter::getPosition() const
125 {
126         return m_position;
127 }
128
129 AUD_DeviceSpecs AUD_SndFileWriter::getSpecs() const
130 {
131         return m_specs;
132 }
133
134 void AUD_SndFileWriter::write(unsigned int length, sample_t* buffer)
135 {
136         length = sf_writef_float(m_sndfile, buffer, length);
137
138         m_position += length;
139 }