| 1 | //////////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: sndfrmt.cpp |
| 3 | // Purpose: wxMMedia |
| 4 | // Author: Guilhem Lavaux |
| 5 | // Created: 1998 |
| 6 | // Updated: December 1998 |
| 7 | // Copyright: (C) 1997, 1998, Guilhem Lavaux |
| 8 | // License: wxWindows license |
| 9 | //////////////////////////////////////////////////////////////////////////////// |
| 10 | #ifdef __GNUG__ |
| 11 | #pragma implementation "sndfrmt.h" |
| 12 | #endif |
| 13 | #include "sndsnd.h" |
| 14 | #include "sndfrmt.h" |
| 15 | #include "sndpcm.h" |
| 16 | |
| 17 | // ---------------------------------------------------------------------------- |
| 18 | // wxSoundDataFormat |
| 19 | // ---------------------------------------------------------------------------- |
| 20 | |
| 21 | wxSoundDataFormat::wxSoundDataFormat() |
| 22 | { |
| 23 | m_srate = 22050; |
| 24 | m_bps = 8; |
| 25 | m_channels = 1; |
| 26 | m_codno = 1; |
| 27 | m_codec = NULL; |
| 28 | m_codchange = FALSE; |
| 29 | m_codcreate = TRUE; |
| 30 | } |
| 31 | |
| 32 | wxSoundDataFormat::wxSoundDataFormat(const wxSoundDataFormat& format) |
| 33 | { |
| 34 | m_srate = format.m_srate; |
| 35 | m_bps = format.m_bps; |
| 36 | m_channels = format.m_channels; |
| 37 | m_codno = format.m_codno; |
| 38 | m_sign = format.m_sign; |
| 39 | m_byteorder = format.m_byteorder; |
| 40 | m_codchange = FALSE; |
| 41 | m_codcreate = TRUE; |
| 42 | m_codec = NULL; |
| 43 | } |
| 44 | |
| 45 | wxSoundDataFormat::~wxSoundDataFormat() |
| 46 | { |
| 47 | wxDELETE(m_codec); |
| 48 | } |
| 49 | |
| 50 | void wxSoundDataFormat::SetChannels(int channels) |
| 51 | { |
| 52 | m_channels = channels; |
| 53 | } |
| 54 | |
| 55 | void wxSoundDataFormat::SetBps(int bps) |
| 56 | { |
| 57 | m_bps = bps; |
| 58 | CodecChange(); |
| 59 | } |
| 60 | |
| 61 | void wxSoundDataFormat::SetSign(int sign) |
| 62 | { |
| 63 | m_sign = sign; |
| 64 | CodecChange(); |
| 65 | } |
| 66 | |
| 67 | void wxSoundDataFormat::SetByteOrder(int byteorder) |
| 68 | { |
| 69 | m_byteorder = byteorder; |
| 70 | CodecChange(); |
| 71 | } |
| 72 | |
| 73 | void wxSoundDataFormat::SetCodecNo(int codno) |
| 74 | { |
| 75 | m_codno = codno; |
| 76 | m_codchange = TRUE; |
| 77 | CodecChange(); |
| 78 | } |
| 79 | |
| 80 | wxSoundCodec *wxSoundDataFormat::GetCodec() |
| 81 | { |
| 82 | if (!m_codcreate) |
| 83 | return NULL; |
| 84 | |
| 85 | if (m_codchange) |
| 86 | wxDELETE(m_codec); |
| 87 | |
| 88 | if (m_codec) |
| 89 | return m_codec; |
| 90 | |
| 91 | m_codchange = FALSE; |
| 92 | m_codec = wxSoundCodec::Get(m_codno); |
| 93 | CodecChange(); |
| 94 | |
| 95 | return m_codec; |
| 96 | } |
| 97 | |
| 98 | void wxSoundDataFormat::CodecChange() |
| 99 | { |
| 100 | wxSoundCodec *codec = GetCodec(); |
| 101 | |
| 102 | if (!codec) |
| 103 | return; |
| 104 | |
| 105 | switch (m_codno) { |
| 106 | case WXSOUND_PCM: { |
| 107 | wxSoundPcmCodec *pcm_codec = (wxSoundPcmCodec *)codec; |
| 108 | |
| 109 | pcm_codec->m_orig_format.SetSampleRate(m_srate); |
| 110 | pcm_codec->m_orig_format.SetBps(m_bps); |
| 111 | pcm_codec->m_orig_format.SetChannels(m_channels); |
| 112 | pcm_codec->m_orig_format.SetByteOrder(m_byteorder); |
| 113 | pcm_codec->m_orig_format.SetSign(m_sign); |
| 114 | break; |
| 115 | } |
| 116 | default: |
| 117 | codec->InitWith(*this); |
| 118 | break; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | wxSoundDataFormat& wxSoundDataFormat::operator =(const wxSoundDataFormat& format) |
| 123 | { |
| 124 | wxDELETE(m_codec); |
| 125 | |
| 126 | m_srate = format.m_srate; |
| 127 | m_bps = format.m_bps; |
| 128 | m_channels = format.m_channels; |
| 129 | m_codno = format.m_codno; |
| 130 | m_sign = format.m_sign; |
| 131 | m_byteorder = format.m_byteorder; |
| 132 | |
| 133 | return *this; |
| 134 | } |
| 135 | |
| 136 | bool wxSoundDataFormat::operator ==(const wxSoundDataFormat& format) const |
| 137 | { |
| 138 | if (m_codno != format.m_codno || m_srate != format.m_srate || |
| 139 | m_bps != format.m_bps || m_channels != format.m_channels) |
| 140 | return FALSE; |
| 141 | |
| 142 | if (m_codno == WXSOUND_PCM && |
| 143 | (m_sign != format.m_sign || m_byteorder != format.m_byteorder)) |
| 144 | return FALSE; |
| 145 | |
| 146 | return TRUE; |
| 147 | } |
| 148 | |
| 149 | // ---------------------------------------------------------------------------- |
| 150 | // wxSoundCodec |
| 151 | // ---------------------------------------------------------------------------- |
| 152 | |
| 153 | #include "sndpcm.h" |
| 154 | #include "sndadpcm.h" |
| 155 | //#include "sndalaw.h" |
| 156 | #include "sndmulaw.h" |
| 157 | |
| 158 | static wxClassInfo *l_sound_formats[] = { |
| 159 | NULL, |
| 160 | CLASSINFO(wxSoundPcmCodec), |
| 161 | CLASSINFO(wxSoundAdpcmCodec), |
| 162 | NULL, |
| 163 | NULL, |
| 164 | NULL, |
| 165 | NULL, // CLASSINFO(wxSoundAlawCodec), |
| 166 | CLASSINFO(wxSoundMulawCodec) |
| 167 | }; |
| 168 | |
| 169 | static int l_nb_formats = WXSIZEOF(l_sound_formats); |
| 170 | |
| 171 | wxSoundCodec::wxSoundCodec() |
| 172 | { |
| 173 | m_in_sound = NULL; |
| 174 | m_out_sound = NULL; |
| 175 | m_init = TRUE; |
| 176 | m_chain_codec = NULL; |
| 177 | } |
| 178 | |
| 179 | wxSoundCodec::~wxSoundCodec() |
| 180 | { |
| 181 | if (m_mode != WAITING) |
| 182 | ExitMode(); |
| 183 | } |
| 184 | |
| 185 | void wxSoundCodec::InitIO(const wxSoundDataFormat& format) |
| 186 | { |
| 187 | m_io_format = format; |
| 188 | } |
| 189 | |
| 190 | void wxSoundCodec::InitMode(ModeType mode) |
| 191 | { |
| 192 | wxStreamBuffer *buf_snd; |
| 193 | |
| 194 | m_mode = mode; |
| 195 | if (!m_chain_codec) { |
| 196 | if (m_mode == ENCODING) { |
| 197 | m_out_sound = new wxStreamBuffer(*this, wxStreamBuffer::write); |
| 198 | m_out_sound->SetBufferIO(1024); |
| 199 | } else { |
| 200 | m_in_sound = new wxStreamBuffer(*this, wxStreamBuffer::read); |
| 201 | m_in_sound->SetBufferIO(1024); |
| 202 | } |
| 203 | } |
| 204 | if (m_chain_codec) { |
| 205 | if (m_chain_before) { |
| 206 | m_chain_codec->SetInStream(m_in_sound); |
| 207 | buf_snd = new wxStreamBuffer(wxStreamBuffer::read_write); |
| 208 | buf_snd->Fixed(FALSE); |
| 209 | m_chain_codec->SetOutStream(buf_snd); |
| 210 | m_chain_codec->Decode(); |
| 211 | buf_snd->Seek(0, wxFromStart); |
| 212 | m_in_sound = buf_snd; |
| 213 | } else { |
| 214 | buf_snd = new wxStreamBuffer(wxStreamBuffer::read_write); |
| 215 | buf_snd->Fixed(FALSE); |
| 216 | |
| 217 | m_chain_codec->SetInStream(buf_snd); |
| 218 | m_chain_codec->SetOutStream(m_out_sound); |
| 219 | m_out_sound = buf_snd; |
| 220 | |
| 221 | buf_snd->Seek(0, wxFromStart); |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | void wxSoundCodec::ExitMode() |
| 227 | { |
| 228 | if (m_chain_codec) { |
| 229 | if (m_chain_before) { |
| 230 | delete m_in_sound; |
| 231 | m_in_sound = m_chain_codec->GetInStream(); |
| 232 | } else { |
| 233 | delete m_out_sound; |
| 234 | m_out_sound = m_chain_codec->GetOutStream(); |
| 235 | } |
| 236 | } |
| 237 | m_mode = WAITING; |
| 238 | } |
| 239 | |
| 240 | bool wxSoundCodec::ChainCodecBefore(wxSoundDataFormat& format) |
| 241 | { |
| 242 | m_chain_codec = format.GetCodec(); |
| 243 | |
| 244 | if (!m_chain_codec) |
| 245 | return FALSE; |
| 246 | |
| 247 | m_chain_before = TRUE; |
| 248 | return TRUE; |
| 249 | } |
| 250 | |
| 251 | bool wxSoundCodec::ChainCodecAfter(wxSoundDataFormat& format) |
| 252 | { |
| 253 | m_chain_codec = format.GetCodec(); |
| 254 | |
| 255 | if (!m_chain_codec) |
| 256 | return FALSE; |
| 257 | |
| 258 | m_chain_before = FALSE; |
| 259 | return TRUE; |
| 260 | } |
| 261 | |
| 262 | void wxSoundCodec::CopyToOutput() |
| 263 | { |
| 264 | m_out_sound->Write(m_in_sound); |
| 265 | } |
| 266 | |
| 267 | size_t wxSoundCodec::Available() |
| 268 | { |
| 269 | return m_io_sndbuf->Available(); |
| 270 | } |
| 271 | |
| 272 | size_t wxSoundCodec::OnSysRead(void *buffer, size_t bsize) |
| 273 | { |
| 274 | wxUint32 s = bsize; |
| 275 | m_io_sndbuf->OnNeedOutputData((char *)buffer, s); |
| 276 | return bsize; |
| 277 | } |
| 278 | |
| 279 | size_t wxSoundCodec::OnSysWrite(const void *buffer, size_t bsize) |
| 280 | { |
| 281 | wxUint32 s = bsize; |
| 282 | m_io_sndbuf->OnBufferInFinished((char *)buffer, s); |
| 283 | return bsize; |
| 284 | } |
| 285 | |
| 286 | wxSoundCodec *wxSoundCodec::Get(int no) |
| 287 | { |
| 288 | if (no < 0 || no >= l_nb_formats) |
| 289 | return NULL; |
| 290 | |
| 291 | if (!l_sound_formats[no]) |
| 292 | return NULL; |
| 293 | |
| 294 | return (wxSoundCodec *)l_sound_formats[no]->CreateObject(); |
| 295 | } |