]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/mmedia/sndaiff.cpp
Rework modal dialog code to not depend on now obsolete wxDIALOG_MODAL flag.
[wxWidgets.git] / contrib / src / mmedia / sndaiff.cpp
CommitLineData
e8482f24
GL
1// --------------------------------------------------------------------------
2// Name: sndaiff.cpp
3// Purpose:
4// Date: 08/11/1999
5// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
6// CVSID: $Id$
7// --------------------------------------------------------------------------
8#ifdef __GNUG__
9#pragma implementation "sndaiff.cpp"
10#endif
11
12#include "wx/wxprec.h"
13
14#ifndef WX_PRECOMP
15 #include "wx/defs.h"
16#endif
17
18#ifdef __BORLANDC__
19 #pragma hdrstop
20#endif
21
22#include "wx/stream.h"
23#include "wx/datstrm.h"
24#include "wx/filefn.h"
25
26#include "wx/mmedia/sndbase.h"
27#include "wx/mmedia/sndcodec.h"
28#include "wx/mmedia/sndfile.h"
29#include "wx/mmedia/sndpcm.h"
30#include "wx/mmedia/sndaiff.h"
31
32#define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24))
33
34#define FORM_SIGNATURE BUILD_SIGNATURE('F','O','R','M')
35#define AIFF_SIGNATURE BUILD_SIGNATURE('A','I','F','F')
36#define AIFC_SIGNATURE BUILD_SIGNATURE('A','I','F','C')
37#define COMM_SIGNATURE BUILD_SIGNATURE('C','O','M','M')
38#define SSND_SIGNATURE BUILD_SIGNATURE('S','S','N','D')
39
40wxSoundAiff::wxSoundAiff(wxInputStream& stream, wxSoundStream& io_sound)
41 : wxSoundFileStream(stream, io_sound)
42{
43 m_base_offset = wxInvalidOffset;
44}
45
46wxSoundAiff::wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound)
47 : wxSoundFileStream(stream, io_sound)
48{
49 m_base_offset = wxInvalidOffset;
50}
51
52wxSoundAiff::~wxSoundAiff()
53{
54}
55
56wxString wxSoundAiff::GetCodecName() const
57{
f815011f 58 return wxT("wxSoundAiff codec");
e8482f24
GL
59}
60
61bool wxSoundAiff::CanRead()
62{
63 wxUint32 signature1, signature2, len;
64
65 if (m_input->Read(&signature1, 4).LastRead() != 4)
66 return FALSE;
67
68 if (wxUINT32_SWAP_ON_BE(signature1) != FORM_SIGNATURE) {
69 m_input->Ungetch(&signature1, 4);
70 return FALSE;
71 }
72
73 m_input->Read(&len, 4);
74 if (m_input->LastRead() != 4) {
75 m_input->Ungetch(&len, m_input->LastRead());
76 m_input->Ungetch(&signature1, 4);
77 return FALSE;
78 }
79
80 if (m_input->Read(&signature2, 4).LastRead() != 4) {
81 m_input->Ungetch(&signature2, m_input->LastRead());
82 m_input->Ungetch(&len, 4);
83 m_input->Ungetch(&signature1, 4);
84 return FALSE;
85 }
86
87 m_input->Ungetch(&signature2, 4);
88 m_input->Ungetch(&len, 4);
89 m_input->Ungetch(&signature1, 4);
90
91 if (
92 wxUINT32_SWAP_ON_BE(signature2) != AIFF_SIGNATURE &&
93 wxUINT32_SWAP_ON_BE(signature2) != AIFC_SIGNATURE)
94 return FALSE;
95
96 return TRUE;
97}
98
99#define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return FALSE; }
100
101bool wxSoundAiff::PrepareToPlay()
102{
103 wxDataInputStream data(*m_input);
104 wxUint32 signature, len, ssnd;
105 bool end_headers;
106
107 if (!m_input) {
108 m_snderror = wxSOUND_INVSTRM;
109 return FALSE;
110 }
111 m_snderror = wxSOUND_NOERROR;
112
113 data.BigEndianOrdered(TRUE);
114
115 FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
116 FAIL_WITH(wxUINT32_SWAP_ON_BE(signature) != FORM_SIGNATURE, wxSOUND_INVSTRM);
117 // "FORM"
118
119 len = data.Read32();
2b3644c7 120 wxUnusedVar(len);
e8482f24
GL
121 FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
122 // dummy len
123
124 FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
125 FAIL_WITH(
126 wxUINT32_SWAP_ON_BE(signature) != AIFF_SIGNATURE &&
127 wxUINT32_SWAP_ON_BE(signature) != AIFC_SIGNATURE, wxSOUND_INVSTRM);
128 // "AIFF" / "AIFC"
129
130 end_headers = FALSE;
131 while (!end_headers) {
132 FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
133
134 len = data.Read32();
135 FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
136
137 switch (wxUINT32_SWAP_ON_BE(signature)) {
138 case COMM_SIGNATURE: { // "COMM"
139 wxUint16 channels, bps;
140 wxUint32 num_samples;
141 double srate;
142 wxSoundFormatPcm sndformat;
143
144 // Get sound data informations
145 data >> channels >> num_samples >> bps >> srate;
146
147 // Convert them in a wxSoundFormat object
148 sndformat.SetSampleRate((wxUint32) srate);
149 sndformat.SetBPS(bps);
150 sndformat.SetChannels(channels);
151 sndformat.Signed(FALSE);
152 sndformat.SetOrder(wxBIG_ENDIAN);
153
154 if (!SetSoundFormat(sndformat))
155 return FALSE;
156 // We pass all data left
157 m_input->SeekI(len-18, wxFromCurrent);
158 break;
159 }
160 case SSND_SIGNATURE: { // "SSND"
161 data >> ssnd;
162 // m_input->SeekI(4, wxFromCurrent); // Pass an INT32
163 // m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
164 m_input->SeekI(ssnd + 4, wxFromCurrent);
165 m_base_offset = m_input->TellI();
166 // len-8 bytes of samples
167 FinishPreparation(len - 8);
168 end_headers = TRUE;
169 break;
170 }
171 default:
172 m_input->SeekI(len, wxFromCurrent);
173 break;
174 }
175 }
176 return TRUE;
177}
178
42c37dec 179bool wxSoundAiff::PrepareToRecord(wxUint32 WXUNUSED(time))
e8482f24
GL
180{
181 // TODO
182 return FALSE;
183}
184
185bool wxSoundAiff::FinishRecording()
186{
187 // TODO
188 return FALSE;
189}
190
42c37dec 191bool wxSoundAiff::RepositionStream(wxUint32 WXUNUSED(position))
e8482f24
GL
192{
193 // If the stream is not seekable "TellI() returns wxInvalidOffset" we cannot reposition stream
194 if (m_base_offset == wxInvalidOffset)
195 return FALSE;
196 m_input->SeekI(m_base_offset, wxFromStart);
197 return TRUE;
198}
199
200wxUint32 wxSoundAiff::GetData(void *buffer, wxUint32 len)
201{
202 return m_input->Read(buffer, len).LastRead();
203}
204
205wxUint32 wxSoundAiff::PutData(const void *buffer, wxUint32 len)
206{
207 return m_output->Write(buffer, len).LastWrite();
208}