]>
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 | ||
4d6306eb GL |
89 | m_sndmode = wxSND_OUTPUT; |
90 | ChangeCodec(wav_hdr.format); | |
91 | ||
92 | m_sndformat.SetSampleRate(wav_hdr.sample_fq); | |
93 | m_sndformat.SetBps(wav_hdr.bits_p_spl); | |
94 | m_sndformat.SetChannels(wav_hdr.channels); | |
95 | ||
96 | if (wav_hdr.format == WXSOUND_PCM) { | |
97 | m_sndformat.SetSign(wxSND_SAMPLE_SIGNED); | |
98 | m_sndformat.SetByteOrder(wxSND_SAMPLE_LE); | |
99 | } | |
100 | ||
101 | wxUint32 sec1 = riff_codec.GetChunkLength() / wav_hdr.byte_p_sec, | |
102 | sec2 = sec1 % 3600; | |
103 | ||
104 | m_sndtime.hours = sec1 / 3600; | |
105 | m_sndtime.minutes = sec2 / 60; | |
106 | m_sndtime.seconds = sec2 % 60; | |
107 | ||
108 | wxSndFileCodec::m_mmerror = wxMMFILE_NOERROR; | |
8a7c9dcc | 109 | wxSndFileCodec::m_fstate = wxSFILE_PREPARED_TO_PLAY; |
4d6306eb GL |
110 | |
111 | return riff_codec.GetChunkLength(); | |
112 | } | |
113 | ||
114 | wxSndWavCodec::~wxSndWavCodec() | |
115 | { | |
116 | } | |
117 | ||
118 | bool wxSndWavCodec::OnNeedData(char *buf, wxUint32 size) | |
119 | { | |
120 | return riff_codec.ReadData(buf, size); | |
121 | } | |
122 | ||
123 | bool wxSndWavCodec::OnWriteData(char *buf, wxUint32 size) | |
124 | { | |
125 | return riff_codec.WriteData(buf, size); | |
126 | } | |
127 | ||
128 | bool wxSndWavCodec::PrepareToRecord(wxUint32 m_fsize) | |
129 | { | |
130 | wxUint32 total_size; | |
131 | ||
132 | if (!riff_codec.RiffReset(RIFF_WRITE)) | |
133 | return FALSE; | |
134 | ||
135 | total_size = 16 + sizeof(wav_hdr) + m_fsize; | |
136 | ||
137 | if (!riff_codec.CreateChunk("RIFF", total_size)) | |
138 | return FALSE; | |
139 | riff_codec.WriteData("WAVE", 4); | |
140 | if (!riff_codec.CreateChunk("fmt ", sizeof(wav_hdr))) | |
141 | return FALSE; | |
142 | ||
9a1b2c28 | 143 | wav_hdr.format = m_sndformat.GetCodecNo(); // PCM_WAV_FORMAT |
4d6306eb GL |
144 | wav_hdr.channels = m_sndformat.GetChannels(); |
145 | wav_hdr.sample_fq = m_sndformat.GetSampleRate(); | |
146 | wav_hdr.byte_p_spl = (m_sndformat.GetBps() / 8) * wav_hdr.channels; | |
147 | wav_hdr.byte_p_sec = m_sndformat.GetCodec()->GetByteRate(); | |
148 | wav_hdr.bits_p_spl = m_sndformat.GetBps(); | |
4d6306eb GL |
149 | |
150 | if (wav_hdr.format == WXSOUND_PCM) { | |
151 | m_sndformat.SetSign(wxSND_SAMPLE_SIGNED); | |
152 | m_sndformat.SetByteOrder(wxSND_SAMPLE_LE); | |
153 | } | |
154 | ||
155 | riff_codec.Write16(wav_hdr.format); | |
156 | riff_codec.Write16(wav_hdr.channels); | |
157 | riff_codec.Write32(wav_hdr.sample_fq); | |
158 | riff_codec.Write32(wav_hdr.byte_p_sec); | |
159 | riff_codec.Write16(wav_hdr.byte_p_spl); | |
160 | riff_codec.Write16(wav_hdr.bits_p_spl); | |
161 | ||
162 | if (!riff_codec.CreateChunk("data", m_fsize)) | |
163 | return FALSE; | |
164 | return TRUE; | |
165 | } | |
166 | ||
167 | void wxSndWavCodec::SetFile(wxInputStream& s, bool preload, bool seekable) | |
168 | { | |
169 | wxMMediaFile::SetFile(s, preload, seekable); | |
170 | if (!seekable) | |
171 | CacheIO(); | |
172 | ||
173 | riff_codec.SetFile((seekable) ? s : *m_istream); | |
174 | } | |
175 | ||
176 | void wxSndWavCodec::SetFile(wxOutputStream& s, bool seekable) | |
177 | { | |
178 | wxMMediaFile::SetFile(s, seekable); | |
179 | if (!seekable) | |
180 | CacheIO(); | |
181 | ||
182 | riff_codec.SetFile((seekable) ? s : *m_ostream); | |
183 | } |