]>
Commit | Line | Data |
---|---|---|
4d6306eb GL |
1 | //////////////////////////////////////////////////////////////////////////////// |
2 | // Name: sndwav.cpp | |
3 | // Purpose: wxMMedia | |
4 | // Author: Guilhem Lavaux | |
5 | // Created: 1997 | |
6 | // Updated: February 1998 | |
7 | // Copyright: (C) 1997, 1998, Guilhem Lavaux | |
8 | // License: wxWindows license | |
9 | //////////////////////////////////////////////////////////////////////////////// | |
10 | #ifdef __GNUG__ | |
11 | #pragma implementation "sndwav.h" | |
12 | #endif | |
13 | ||
14 | #ifdef WX_PRECOMP | |
15 | #include "wx_prec.h" | |
16 | #else | |
17 | #include "wx/wx.h" | |
18 | #endif | |
19 | #include "sndwav.h" | |
20 | #include "sndfrmt.h" | |
21 | #include "sndpcm.h" | |
22 | ||
23 | #ifdef __BORLANDC__ | |
24 | #pragma hdrstop | |
25 | #endif | |
26 | ||
27 | wxSndWavCodec::wxSndWavCodec() | |
28 | : wxSndFileCodec(), riff_codec() | |
29 | { | |
30 | m_sndtime.hours = -1; | |
31 | } | |
32 | ||
33 | wxSndWavCodec::wxSndWavCodec(wxOutputStream& s, bool seekable) | |
34 | : wxSndFileCodec(s, seekable) | |
35 | { | |
36 | if (!seekable) | |
37 | CacheIO(); | |
38 | riff_codec = wxRiffCodec(*m_ostream); | |
39 | m_sndtime.hours = -1; | |
40 | } | |
41 | ||
42 | wxSndWavCodec::wxSndWavCodec(wxInputStream& s, bool preload, bool seekable) | |
43 | : wxSndFileCodec(s, preload, seekable) | |
44 | { | |
45 | if (!seekable) | |
46 | CacheIO(); | |
47 | ||
48 | riff_codec = wxRiffCodec(*m_istream); | |
49 | m_sndtime.hours = -1; | |
50 | } | |
51 | ||
52 | wxSndWavCodec::wxSndWavCodec(const wxString& fname) | |
53 | : wxSndFileCodec(fname) | |
54 | { | |
55 | riff_codec = wxRiffCodec(*m_istream); | |
56 | m_sndtime.hours = -1; | |
57 | } | |
58 | ||
59 | wxUint32 wxSndWavCodec::PrepareToPlay() | |
60 | { | |
61 | if (!riff_codec.RiffReset(RIFF_READ)) | |
62 | return 0; | |
63 | ||
64 | if (!riff_codec.FindChunk("RIFF", TRUE)) { | |
65 | wxSndFileCodec::m_mmerror = wxMMFILE_INVALID; | |
66 | return 0; | |
67 | } | |
68 | ||
69 | char tmp_buf[5]; | |
70 | riff_codec.ReadData(tmp_buf, 4); | |
71 | tmp_buf[4] = 0; | |
72 | if (wxString("WAVE") != tmp_buf) { | |
73 | wxSndFileCodec::m_mmerror = wxMMFILE_INVALID; | |
74 | return 0; | |
75 | } | |
76 | if (!riff_codec.FindChunk("fmt ", TRUE)) | |
77 | return 0; | |
78 | ||
79 | riff_codec.Read16(wav_hdr.format); | |
80 | riff_codec.Read16(wav_hdr.channels); | |
81 | riff_codec.Read32(wav_hdr.sample_fq); | |
82 | riff_codec.Read32(wav_hdr.byte_p_sec); | |
83 | riff_codec.Read16(wav_hdr.byte_p_spl); | |
84 | riff_codec.Read16(wav_hdr.bits_p_spl); | |
85 | ||
86 | if (!riff_codec.FindChunk("data")) | |
87 | return 0; | |
88 | ||
89 | m_sndformat.SetSampleRate(wav_hdr.sample_fq); | |
90 | m_sndformat.SetBps(wav_hdr.bits_p_spl); | |
91 | m_sndformat.SetChannels(wav_hdr.channels); | |
92 | m_sndmode = wxSND_OUTPUT; | |
93 | ChangeCodec(wav_hdr.format); | |
94 | ||
95 | m_sndformat.SetSampleRate(wav_hdr.sample_fq); | |
96 | m_sndformat.SetBps(wav_hdr.bits_p_spl); | |
97 | m_sndformat.SetChannels(wav_hdr.channels); | |
98 | ||
99 | if (wav_hdr.format == WXSOUND_PCM) { | |
100 | m_sndformat.SetSign(wxSND_SAMPLE_SIGNED); | |
101 | m_sndformat.SetByteOrder(wxSND_SAMPLE_LE); | |
102 | } | |
103 | ||
104 | wxUint32 sec1 = riff_codec.GetChunkLength() / wav_hdr.byte_p_sec, | |
105 | sec2 = sec1 % 3600; | |
106 | ||
107 | m_sndtime.hours = sec1 / 3600; | |
108 | m_sndtime.minutes = sec2 / 60; | |
109 | m_sndtime.seconds = sec2 % 60; | |
110 | ||
111 | wxSndFileCodec::m_mmerror = wxMMFILE_NOERROR; | |
112 | ||
113 | return riff_codec.GetChunkLength(); | |
114 | } | |
115 | ||
116 | wxSndWavCodec::~wxSndWavCodec() | |
117 | { | |
118 | } | |
119 | ||
120 | bool wxSndWavCodec::OnNeedData(char *buf, wxUint32 size) | |
121 | { | |
122 | return riff_codec.ReadData(buf, size); | |
123 | } | |
124 | ||
125 | bool wxSndWavCodec::OnWriteData(char *buf, wxUint32 size) | |
126 | { | |
127 | return riff_codec.WriteData(buf, size); | |
128 | } | |
129 | ||
130 | bool wxSndWavCodec::PrepareToRecord(wxUint32 m_fsize) | |
131 | { | |
132 | wxUint32 total_size; | |
133 | ||
134 | if (!riff_codec.RiffReset(RIFF_WRITE)) | |
135 | return FALSE; | |
136 | ||
137 | total_size = 16 + sizeof(wav_hdr) + m_fsize; | |
138 | ||
139 | if (!riff_codec.CreateChunk("RIFF", total_size)) | |
140 | return FALSE; | |
141 | riff_codec.WriteData("WAVE", 4); | |
142 | if (!riff_codec.CreateChunk("fmt ", sizeof(wav_hdr))) | |
143 | return FALSE; | |
144 | ||
145 | wav_hdr.format = 1; // PCM_WAV_FORMAT | |
146 | wav_hdr.channels = m_sndformat.GetChannels(); | |
147 | wav_hdr.sample_fq = m_sndformat.GetSampleRate(); | |
148 | wav_hdr.byte_p_spl = (m_sndformat.GetBps() / 8) * wav_hdr.channels; | |
149 | wav_hdr.byte_p_sec = m_sndformat.GetCodec()->GetByteRate(); | |
150 | wav_hdr.bits_p_spl = m_sndformat.GetBps(); | |
151 | ChangeCodec(WXSOUND_PCM); | |
152 | ||
153 | if (wav_hdr.format == WXSOUND_PCM) { | |
154 | m_sndformat.SetSign(wxSND_SAMPLE_SIGNED); | |
155 | m_sndformat.SetByteOrder(wxSND_SAMPLE_LE); | |
156 | } | |
157 | ||
158 | riff_codec.Write16(wav_hdr.format); | |
159 | riff_codec.Write16(wav_hdr.channels); | |
160 | riff_codec.Write32(wav_hdr.sample_fq); | |
161 | riff_codec.Write32(wav_hdr.byte_p_sec); | |
162 | riff_codec.Write16(wav_hdr.byte_p_spl); | |
163 | riff_codec.Write16(wav_hdr.bits_p_spl); | |
164 | ||
165 | if (!riff_codec.CreateChunk("data", m_fsize)) | |
166 | return FALSE; | |
167 | return TRUE; | |
168 | } | |
169 | ||
170 | void wxSndWavCodec::SetFile(wxInputStream& s, bool preload, bool seekable) | |
171 | { | |
172 | wxMMediaFile::SetFile(s, preload, seekable); | |
173 | if (!seekable) | |
174 | CacheIO(); | |
175 | ||
176 | riff_codec.SetFile((seekable) ? s : *m_istream); | |
177 | } | |
178 | ||
179 | void wxSndWavCodec::SetFile(wxOutputStream& s, bool seekable) | |
180 | { | |
181 | wxMMediaFile::SetFile(s, seekable); | |
182 | if (!seekable) | |
183 | CacheIO(); | |
184 | ||
185 | riff_codec.SetFile((seekable) ? s : *m_ostream); | |
186 | } |