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