1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
7 // --------------------------------------------------------------------------
9 #pragma implementation "sndcpcm.cpp"
12 #include <wx/wxprec.h>
17 wxSoundStreamPcm::wxSoundStreamPcm(wxSoundStream
& sndio
)
18 : wxSoundStreamCodec(sndio
)
21 m_function_out
= NULL
;
24 wxSoundStreamPcm::~wxSoundStreamPcm()
30 #include "converter.def"
34 #include "converter.def"
37 wxSoundStreamPcm::ConverterType s_convert_out_16_to_8
[] = {
39 Convert_16to8_U2S_16_no
,
42 Convert_16to8_U2S_16_yes
,
46 wxSoundStreamPcm::ConverterType s_convert_out_16
[] = {
49 Convert_U2S_SWAP_16_no
,
50 Convert_U2S_SWAP_16_yes
,
55 wxSoundStreamPcm::ConverterType s_convert_out_8
[] = {
70 wxSoundStreamPcm::ConverterType s_convert_in_8_to_16
[] = {
73 Convert_8to16_U2S_SWAP_8
,
79 wxSoundStreamPcm::ConverterType
*s_convert_in_16
= s_convert_out_16
;
81 wxSoundStreamPcm::ConverterType
*s_convert_in_8
= s_convert_out_8
;
84 #define CONVERTER_SIGN 1
85 #define CONVERTER_SIGN_SWAP 2
86 #define CONVERTER_SWAP_SIGN_SWAP 3
87 #define CONVERTER_SWAP_SIGN 4
88 #define CONVERTER_SWAP 5
89 #define CONVERTER_SIGN_STEREO_MONO 6
90 #define CONVERTER_SIGN_SWAP_STEREO_MONO 7
91 #define CONVERTER_SWAP_SIGN_SWAP_STEREO_MONO 8
92 #define CONVERTER_SWAP_SIGN_STEREO_MONO 9
93 #define CONVERTER_SWAP_STEREO_MONO 10
94 #define CONVERTER_STEREO_MONO 11
97 // TODO: Read() and Write() aren't really safe. If you give it a buffer which
98 // is not aligned on 8, you may crash (See converter.def).
101 wxSoundStream
& wxSoundStreamPcm::Read(void *buffer
, wxUint32 len
)
106 if (!m_function_in
) {
107 m_sndio
->Read(buffer
, len
);
108 m_lastcount
= m_sndio
->GetLastAccess();
109 m_snderror
= m_sndio
->GetError();
113 real_len
= (m_16_to_8
) ? len
/ 2 : len
;
115 tmp_buf
= new char[real_len
];
117 m_sndio
->Read(tmp_buf
, real_len
);
118 m_lastcount
= m_sndio
->GetLastAccess();
119 m_snderror
= m_sndio
->GetError();
120 if (m_snderror
!= wxSOUND_NOERR
)
123 m_function_in(tmp_buf
, (char *)buffer
, m_lastcount
);
133 wxSoundStream
& wxSoundStreamPcm::Write(const void *buffer
, wxUint32 len
)
139 return m_sndio
->Write(buffer
, len
);
141 len2
= (m_16_to_8
) ? len
/ 2 : len
;
143 tmp_buf
= new char[len2
];
144 m_function_out((const char *)buffer
, tmp_buf
, len
);
145 m_sndio
->Write(tmp_buf
, len
);
148 m_lastcount
= (m_16_to_8
) ?
149 (m_sndio
->GetLastAccess() * 2) : m_sndio
->GetLastAccess();
154 bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase
& format
)
156 wxSoundFormatBase
*new_format
;
157 wxSoundFormatPcm
*pcm_format
, *pcm_format2
;
158 ConverterType
*current_table_out
, *current_table_in
;
162 if (m_sndio
->SetSoundFormat(format
)) {
163 m_function_out
= NULL
;
164 m_function_in
= NULL
;
167 if (format
.GetType() != wxSOUND_PCM
) {
168 m_snderror
= wxSOUND_INVFRMT
;
174 new_format
= m_sndio
->GetSoundFormat().Clone();
175 pcm_format
= (wxSoundFormatPcm
*)&format
;
176 pcm_format2
= (wxSoundFormatPcm
*)new_format
;
179 if (pcm_format
->GetBPS() != pcm_format2
->GetBPS()) {
181 current_table_out
= s_convert_out_16_to_8
;
182 current_table_in
= s_convert_in_8_to_16
;
183 } else if (pcm_format
->GetBPS() == 16) {
184 current_table_out
= s_convert_out_16
;
185 current_table_in
= s_convert_in_16
;
187 current_table_out
= s_convert_out_8
;
188 current_table_in
= s_convert_in_8
;
191 change_sign
= (pcm_format2
->Signed() != pcm_format
->Signed());
193 #define MY_ORDER wxBYTE_ORDER
194 #if wxBYTE_ORDER == wxLITTLE_ENDIAN
195 #define OTHER_ORDER wxBIG_ENDIAN
197 #define OTHER_ORDER wxLITTLE_ENDIAN
200 if (pcm_format
->GetOrder() == OTHER_ORDER
&&
201 pcm_format2
->GetOrder() == OTHER_ORDER
&& change_sign
)
202 index
= CONVERTER_SWAP_SIGN_SWAP
;
204 else if (pcm_format
->GetOrder() == OTHER_ORDER
&&
205 pcm_format2
->GetOrder() == MY_ORDER
&& change_sign
)
206 index
= CONVERTER_SWAP_SIGN
;
208 else if (pcm_format
->GetOrder() == MY_ORDER
&&
209 pcm_format
->GetOrder() == OTHER_ORDER
&& change_sign
)
210 index
= CONVERTER_SIGN_SWAP
;
212 else if (!change_sign
&&
213 pcm_format
->GetOrder() != pcm_format2
->GetOrder())
214 index
= CONVERTER_SWAP
;
219 m_function_out
= current_table_out
[index
];
220 m_function_in
= current_table_in
[index
];
222 m_sndio
->SetSoundFormat(*new_format
);
223 m_sndformat
= new_format
;