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