919a76e4ca497ccdc3070fc298388850626f9d33
[asdcplib.git] / src / PCMParserList.cpp
1 /*
2 Copyright (c) 2004-2009, 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    PCMParserList.cpp
28     \version $Id$
29     \brief   Read WAV file(s), multiplex multiple PCM frame buffers into one
30 */
31
32 #include <PCMParserList.h>
33 #include <assert.h>
34
35 using namespace ASDCP;
36
37
38 ASDCP::ParserInstance::ParserInstance() : m_p(0), m_SampleSize(0)
39 {
40 }
41
42 ASDCP::ParserInstance::~ParserInstance()
43 {
44 }
45
46 // PCM::CalcSampleSize(ADesc);
47 Result_t
48 ASDCP::ParserInstance::OpenRead(const char* filename, Rational& PictureRate)
49 {
50   ASDCP_TEST_NULL_STR(filename);
51
52   Result_t result = Parser.OpenRead(filename, PictureRate);
53
54   if ( ASDCP_SUCCESS(result) )
55     result = Parser.FillAudioDescriptor(ADesc);
56
57   if ( ASDCP_SUCCESS(result) )
58     {
59       ADesc.SampleRate = PictureRate;
60       m_SampleSize = PCM::CalcSampleSize(ADesc);
61       result = FB.Capacity(PCM::CalcFrameBufferSize(ADesc));
62     }
63
64   return result;
65 }
66
67
68 // deposit the next available sample into the given framebuffer
69 Result_t
70 ASDCP::ParserInstance::PutSample(byte_t* p)
71 {
72   ASDCP_TEST_NULL(p);
73
74   memcpy(p, m_p, m_SampleSize);
75   m_p += m_SampleSize;
76   return RESULT_OK;
77 }
78
79
80 //
81 Result_t
82 ASDCP::ParserInstance::ReadFrame()
83 {
84   Result_t result = Parser.ReadFrame(FB);
85   m_p = ASDCP_SUCCESS(result) ? FB.RoData() : 0;
86   return result;
87 }
88
89
90 //------------------------------------------------------------------------------------------
91 //
92
93
94 //
95 ASDCP::PCMParserList::PCMParserList() : m_ChannelCount(0)
96 {
97 }
98
99 ASDCP::PCMParserList::~PCMParserList()
100 {
101   while ( ! empty() )
102     {
103       delete back();
104       pop_back();
105     }
106 }
107
108
109 //
110 Result_t
111 ASDCP::PCMParserList::OpenRead(ui32_t argc, const char** argv, Rational& PictureRate)
112 {
113   ASDCP_TEST_NULL_STR(argv);
114   Result_t result = RESULT_OK;
115
116   for ( ui32_t i = 0; i < argc && ASDCP_SUCCESS(result); i++ )
117     {
118       ParserInstance* I = new ParserInstance;
119       result = I->OpenRead(argv[i], PictureRate);
120
121       if ( ASDCP_SUCCESS(result) )
122         {
123           if ( i == 0 )
124             m_ADesc = I->ADesc;
125
126           else
127             m_ADesc.BlockAlign += I->ADesc.BlockAlign;
128
129           m_ChannelCount += I->ADesc.ChannelCount;
130         }
131
132       if ( ASDCP_SUCCESS(result) )
133         result = I->FB.Capacity(PCM::CalcFrameBufferSize(m_ADesc));
134
135       if ( ASDCP_SUCCESS(result) )
136         push_back(I);
137     }
138
139   m_ADesc.ChannelCount = m_ChannelCount;
140   m_ADesc.AvgBps = m_ADesc.AvgBps * m_ChannelCount;
141
142   if ( ASDCP_FAILURE(result) )
143     clear();
144   
145   return result;
146 }
147
148 //
149 Result_t
150 ASDCP::PCMParserList::FillAudioDescriptor(PCM::AudioDescriptor& ADesc) const
151 {
152   ADesc = m_ADesc;
153   return RESULT_OK;
154 }
155
156 //
157 Result_t
158 ASDCP::PCMParserList::Reset()
159 {
160   Result_t result = RESULT_OK;
161   PCMParserList::iterator self_i;
162
163   for ( self_i = begin(); self_i != end() && ASDCP_SUCCESS(result) ; self_i++ )
164     result = (*self_i)->Parser.Reset();
165
166   return result;
167 }
168
169
170 //
171 Result_t
172 ASDCP::PCMParserList::ReadFrame(PCM::FrameBuffer& OutFB)
173 {
174   Result_t result = RESULT_OK;
175
176   if ( size() == 1 )
177     return front()->Parser.ReadFrame(OutFB);
178
179   PCMParserList::iterator self_i;
180   assert(PCM::CalcFrameBufferSize(m_ADesc) <= OutFB.Capacity());
181
182   for ( self_i = begin(); self_i != end() && ASDCP_SUCCESS(result) ; self_i++ )
183     result = (*self_i)->ReadFrame();
184
185   if ( ASDCP_SUCCESS(result) )
186     {
187       OutFB.Size(PCM::CalcFrameBufferSize(m_ADesc));
188
189       //      ui32_t sample_size = (PCM::CalcSampleSize(m_ADesc));
190       byte_t* Out_p = OutFB.Data();
191       byte_t* End_p = Out_p + OutFB.Size();
192
193       while ( Out_p < End_p && ASDCP_SUCCESS(result) )
194         {
195           self_i = begin();
196
197           while ( self_i != end() && ASDCP_SUCCESS(result) )
198             {
199               result = (*self_i)->PutSample(Out_p);
200               Out_p += (*self_i)->SampleSize();
201               self_i++;
202             }
203         }
204
205       assert(Out_p == End_p);
206     }
207
208   return result;
209 }
210
211 //
212 // end PCMParserList.cpp
213 //