]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia2/lib/sndcpcm.cpp
Fixed thread sample SEGV on wxGTK
[wxWidgets.git] / utils / wxMMedia2 / lib / sndcpcm.cpp
1 // --------------------------------------------------------------------------
2 // Name: sndcpcm.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 "sndcpcm.cpp"
10 #endif
11
12 #include <wx/wxprec.h>
13 #include "sndbase.h"
14 #include "sndpcm.h"
15 #include "sndcpcm.h"
16
17 wxSoundStreamPcm::wxSoundStreamPcm(wxSoundStream& sndio)
18 : wxSoundStreamCodec(sndio)
19 {
20 m_function_in = NULL;
21 m_function_out = NULL;
22 }
23
24 wxSoundStreamPcm::~wxSoundStreamPcm()
25 {
26 }
27
28
29 #define SWAP_BYTES 0
30 #include "converter.def"
31 #undef SWAP_BYTES
32
33 #define SWAP_BYTES 1
34 #include "converter.def"
35 #undef SWAP_BYTES
36
37 wxSoundStreamPcm::ConverterType s_convert_16_to_8[] = {
38 Convert_16to8_16_no,
39 Convert_16to8_U2S_16_no,
40 NULL,
41 NULL,
42 Convert_16to8_U2S_16_yes,
43 Convert_16to8_16_yes,
44 };
45
46 wxSoundStreamPcm::ConverterType s_convert_16[] = {
47 NULL,
48 Convert_U2S_16_no,
49 Convert_U2S_SWAP_16_no,
50 Convert_U2S_SWAP_16_yes,
51 Convert_U2S_16_yes,
52 Convert_SWAP_16_no
53 };
54
55 wxSoundStreamPcm::ConverterType s_convert_8[] = {
56 NULL,
57 Convert_U2S_8,
58 Convert_U2S_8,
59 Convert_U2S_8,
60 Convert_U2S_8,
61 NULL
62 };
63
64 #define CONVERTER 0
65 #define CONVERTER_SIGN 1
66 #define CONVERTER_SIGN_SWAP 2
67 #define CONVERTER_SWAP_SIGN_SWAP 3
68 #define CONVERTER_SWAP_SIGN 4
69 #define CONVERTER_SWAP 5
70
71 wxSoundStream& wxSoundStreamPcm::Read(void *buffer, size_t len)
72 {
73 if (!m_function_in) {
74 m_sndio->Read(buffer, len);
75 m_lastcount = m_sndio->GetLastAccess();
76 m_snderror = m_sndio->GetError();
77 return *this;
78 }
79
80 // TODO
81 m_sndio->Read(buffer, len);
82 m_lastcount = m_sndio->GetLastAccess();
83 m_snderror = m_sndio->GetError();
84 return *this;
85 }
86
87 wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, size_t len)
88 {
89 char *tmp_buf;
90 size_t len2;
91
92 if (!m_function_out)
93 return m_sndio->Write(buffer, len);
94
95 len2 = (m_16_to_8) ? len / 2 : len;
96
97 tmp_buf = new char[len2];
98 m_function_out((const char *)buffer, tmp_buf, len);
99 m_sndio->Write(tmp_buf, len);
100 delete[] tmp_buf;
101
102 m_lastcount = (m_16_to_8) ?
103 (m_sndio->GetLastAccess() * 2) : m_sndio->GetLastAccess();
104
105 return *this;
106 }
107
108 bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
109 {
110 wxSoundFormatBase *new_format;
111 wxSoundFormatPcm *pcm_format, *pcm_format2;
112 ConverterType *current_table;
113 int index;
114 bool change_sign;
115
116 if (m_sndio->SetSoundFormat(format)) {
117 m_function_out = NULL;
118 m_function_in = NULL;
119 return TRUE;
120 }
121 if (format.GetType() != wxSOUND_PCM) {
122 m_snderror = wxSOUND_INVFRMT;
123 return FALSE;
124 }
125 if (m_sndformat)
126 delete m_sndformat;
127
128 new_format = m_sndio->GetSoundFormat().Clone();
129 pcm_format = (wxSoundFormatPcm *)&format;
130 pcm_format2 = (wxSoundFormatPcm *)new_format;
131
132 m_16_to_8 = FALSE;
133 if (pcm_format->GetBPS() == 16 && pcm_format2->GetBPS() == 8) {
134 m_16_to_8 = TRUE;
135 current_table = s_convert_16_to_8;
136 } else if (pcm_format->GetBPS() == 16)
137 current_table = s_convert_16;
138 else
139 current_table = s_convert_8;
140
141 change_sign = (pcm_format2->Signed() != pcm_format->Signed());
142
143 #define MY_ORDER wxBYTE_ORDER
144 #if wxBYTE_ORDER == wxLITTLE_ENDIAN
145 #define OTHER_ORDER wxBIG_ENDIAN
146 #else
147 #define OTHER_ORDER wxLITTLE_ENDIAN
148 #endif
149
150 if (pcm_format->GetOrder() == OTHER_ORDER &&
151 pcm_format2->GetOrder() == OTHER_ORDER && change_sign)
152 index = CONVERTER_SWAP_SIGN_SWAP;
153
154 else if (pcm_format->GetOrder() == OTHER_ORDER &&
155 pcm_format2->GetOrder() == MY_ORDER && change_sign)
156 index = CONVERTER_SWAP_SIGN;
157
158 else if (pcm_format->GetOrder() == MY_ORDER &&
159 pcm_format->GetOrder() == OTHER_ORDER && change_sign)
160 index = CONVERTER_SIGN_SWAP;
161
162 else if (!change_sign &&
163 pcm_format->GetOrder() != pcm_format2->GetOrder())
164 index = CONVERTER_SWAP;
165
166 else
167 index = CONVERTER;
168
169 m_function_out = current_table[index];
170 // m_function_in = current_table[index+1];
171
172 m_sndio->SetSoundFormat(*new_format);
173 m_sndformat = new_format;
174 return TRUE;
175 }