Fix Object ref not being written: this prevented GenericStreamTextBasedSet to be...
[asdcplib.git] / src / PCMDataProviders.cpp
1 /*
2 Copyright (c) 20013-2013, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 /*! \file    PCMDataProviders.cpp
28     \version $Id$
29     \brief   Implementation of PCM sample data providers for WAV, AtmosSync and Silence.
30 */
31
32 #include <PCMDataProviders.h>
33
34 #include <KM_log.h>
35
36 using namespace ASDCP;
37 using namespace Kumu;
38
39 ASDCP::PCMDataProviderInterface::~PCMDataProviderInterface() {}
40
41 //
42 ASDCP::WAVDataProvider::WAVDataProvider()
43     : m_Parser(), m_FB(), m_ADesc(), m_SampleSize(0), m_ptr(NULL)
44 {}
45
46 ASDCP::WAVDataProvider::~WAVDataProvider()
47 {}
48
49 Result_t
50 ASDCP::WAVDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten)
51 {
52   ASDCP_TEST_NULL(buf);
53   ASDCP_TEST_NULL(m_ptr);
54   if ( numChannels > m_ADesc.ChannelCount)
55   {
56     DefaultLogSink().Error("Requested %u channels from a wav file with %u channel.", numChannels,
57                            m_ADesc.ChannelCount);
58     return RESULT_FAIL;
59   }
60   *bytesWritten = m_SampleSize * numChannels;
61   ::memcpy(buf, m_ptr, *bytesWritten);
62   m_ptr += *bytesWritten;
63   return RESULT_OK;
64 }
65
66 Result_t
67 ASDCP::WAVDataProvider::ReadFrame()
68 {
69   Result_t result = m_Parser.ReadFrame(m_FB);
70   m_ptr = ASDCP_SUCCESS(result) ? m_FB.RoData() : NULL;
71   return result;
72 }
73
74 Result_t
75 ASDCP::WAVDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const
76 {
77   ADesc = m_ADesc;
78   return RESULT_OK;
79 }
80
81 Result_t
82 ASDCP::WAVDataProvider::Reset()
83 {
84     return m_Parser.Reset();
85 }
86
87 Result_t
88 ASDCP::WAVDataProvider::OpenRead(const char* filename, const Rational& PictureRate)
89 {
90   ASDCP_TEST_NULL_STR(filename);
91
92   Result_t result = m_Parser.OpenRead(filename, PictureRate);
93
94   if ( ASDCP_SUCCESS(result) )
95     result = m_Parser.FillAudioDescriptor(m_ADesc);
96
97   if ( ASDCP_SUCCESS(result) )
98   {
99     m_ADesc.EditRate = PictureRate;
100     m_SampleSize = ((m_ADesc.QuantizationBits + 7) / 8);
101     result = m_FB.Capacity(PCM::CalcFrameBufferSize(m_ADesc));
102   }
103
104   return result;
105 }
106
107 //
108 ASDCP::AtmosSyncDataProvider::AtmosSyncDataProvider(const ui16_t bitsPerSample, const ui32_t sampleRate,
109                                                     const ASDCP::Rational& editRate, const byte_t* uuid)
110     : m_Generator(bitsPerSample, sampleRate, editRate, uuid), m_FB(), m_ADesc(), m_SampleSize()
111 {
112     m_Generator.FillAudioDescriptor(m_ADesc);
113     m_SampleSize = PCM::CalcSampleSize(m_ADesc);
114     m_FB.Capacity(PCM::CalcFrameBufferSize(m_ADesc));
115 }
116
117 ASDCP::AtmosSyncDataProvider::~AtmosSyncDataProvider()
118 {}
119
120 Result_t
121 ASDCP::AtmosSyncDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten)
122 {
123   ASDCP_TEST_NULL(buf);
124   ASDCP_TEST_NULL(m_ptr);
125   if ( numChannels > m_ADesc.ChannelCount)
126   {
127     DefaultLogSink().Error("Requested %u channels from a wav file with %u channel.", numChannels,
128                            m_ADesc.ChannelCount);
129     return RESULT_FAIL;
130   }
131
132   (*bytesWritten) = m_SampleSize;
133   ::memcpy(buf, m_ptr, m_SampleSize);
134   m_ptr += m_SampleSize;
135   return RESULT_OK;
136 }
137
138 Result_t
139 ASDCP::AtmosSyncDataProvider::ReadFrame()
140 {
141   Result_t result = m_Generator.ReadFrame(m_FB);
142   m_ptr = ASDCP_SUCCESS(result) ? m_FB.RoData() : NULL;
143   return result;
144 }
145
146 Result_t
147 ASDCP::AtmosSyncDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const
148 {
149   ADesc = m_ADesc;
150   return RESULT_OK;
151 }
152
153 Result_t
154 ASDCP::AtmosSyncDataProvider::Reset()
155 {
156     return m_Generator.Reset();
157 }
158
159 //
160 ASDCP::SilenceDataProvider::SilenceDataProvider(const ui16_t numChannels, const ui16_t bitsPerSample,
161                                                 const ui32_t sampleRate, const ASDCP::Rational& editRate)
162     : m_ADesc(), m_SampleSize(0)
163 {
164     m_SampleSize = ((bitsPerSample + 7) / 8);
165     m_ADesc.EditRate = editRate;
166     m_ADesc.AudioSamplingRate = Rational(sampleRate, 1);
167     m_ADesc.ChannelCount = numChannels;
168     m_ADesc.QuantizationBits = bitsPerSample;
169     m_ADesc.BlockAlign = numChannels * m_SampleSize;
170     m_ADesc.AvgBps = sampleRate * m_ADesc.BlockAlign;
171 }
172
173 ASDCP::SilenceDataProvider::~SilenceDataProvider()
174 {}
175
176 Result_t
177 ASDCP::SilenceDataProvider::PutSample(const ui32_t numChannels, byte_t* buf, ui32_t* bytesWritten)
178 {
179   ASDCP_TEST_NULL(buf);
180   if ( numChannels > m_ADesc.ChannelCount)
181   {
182     DefaultLogSink().Error("Requested %u channels from a wav file with %u channel.", numChannels,
183                            m_ADesc.ChannelCount);
184     return RESULT_FAIL;
185   }
186   (*bytesWritten) = m_SampleSize * numChannels;
187   ::memset(buf, 0, (*bytesWritten));
188   return RESULT_OK;
189 }
190
191 Result_t
192 ASDCP::SilenceDataProvider::ReadFrame()
193 {
194     // no op
195     return RESULT_OK;
196 }
197
198 Result_t
199 ASDCP::SilenceDataProvider::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const
200 {
201   ADesc = m_ADesc;
202   return RESULT_OK;
203 }
204
205 Result_t
206 ASDCP::SilenceDataProvider::Reset()
207 {
208     //no op
209     return RESULT_OK;
210 }