// m_input->SeekI(4, wxFromCurrent); // Pass an INT32
// m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
m_input->SeekI(ssnd + 4, wxFromCurrent);
+ FinishPreparation(len - 4);
end_headers = TRUE;
break;
}
#include "converter.def"
+// -----------------------------------------------------------------------
+// Main PCM stream converter table
+// -----------------------------------------------------------------------
wxSoundStreamPcm::ConverterType s_converters[] = {
NULL,
Convert_8_8_sign, /* 8 -> 8 sign */
//
// TODO: Read() and Write() aren't really safe. If you give it a buffer which
-// is not aligned on 8, you may crash (See converter.def).
+// is not aligned on 2, you may crash (See converter.def).
//
wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len)
pcm_format = (wxSoundFormatPcm *)&format;
pcm_format2 = (wxSoundFormatPcm *)new_format;
+ // ----------------------------------------------------
+ // Select table to use:
+ // * 8 bits -> 8 bits
+ // * 16 bits -> 8 bits
+ // * 8 bits -> 16 bits
+ // * 16 bits -> 16 bits
+
m_16_to_8 = FALSE;
if (pcm_format->GetBPS() != pcm_format2->GetBPS()) {
m_16_to_8 = TRUE;
#define OTHER_ORDER wxLITTLE_ENDIAN
#endif
+ // --------------------------------------------------------
+ // Find the good converter !
+
+
if (pcm_format->GetOrder() == OTHER_ORDER &&
pcm_format2->GetOrder() == OTHER_ORDER && change_sign)
index = CONVERT_SWAP_SIGN_SWAP;
: m_codec(io_sound), m_sndio(&io_sound),
m_input(&stream), m_output(NULL), m_state(wxSOUND_FILE_STOPPED)
{
+ m_length = 0;
+ m_bytes_left = 0;
+ m_prepared = FALSE;
}
wxSoundFileStream::wxSoundFileStream(wxOutputStream& stream,
: m_codec(io_sound), m_sndio(&io_sound),
m_input(NULL), m_output(&stream), m_state(wxSOUND_FILE_STOPPED)
{
+ m_length = 0;
+ m_bytes_left = 0;
+ m_prepared = FALSE;
}
wxSoundFileStream::~wxSoundFileStream()
if (m_state != wxSOUND_FILE_STOPPED)
return FALSE;
- if (!PrepareToPlay())
- return FALSE;
+ if (!m_prepared)
+ if (!PrepareToPlay())
+ return FALSE;
m_state = wxSOUND_FILE_PLAYING;
if (!PrepareToRecord(time))
return FALSE;
- m_len = m_sndformat->GetBytesFromTime(time);
+ FinishPreparation(m_sndformat->GetBytesFromTime(time));
m_state = wxSOUND_FILE_RECORDING;
if (!StartProduction(wxSOUND_INPUT))
if (!StopProduction())
return FALSE;
+ m_prepared = FALSE;
+
if (m_state == wxSOUND_FILE_RECORDING)
if (!FinishRecording()) {
m_state = wxSOUND_FILE_STOPPED;
return m_codec.StopProduction();
}
+void wxSoundFileStream::FinishPreparation(wxUint32 len)
+{
+ m_bytes_left = m_length = len;
+ m_prepared = TRUE;
+}
+
+wxUint32 wxSoundFileStream::GetLength()
+{
+ if (m_input && !m_prepared && GetError() == wxSOUND_NOERR)
+ return (PrepareToPlay()) ? m_length : 0;
+
+ return m_length;
+}
+
+wxUint32 wxSoundFileStream::GetPosition()
+{
+ if (!m_prepared && m_input != NULL && GetError() == wxSOUND_NOERR)
+ PrepareToPlay();
+
+ return m_length-m_bytes_left;
+}
+
void wxSoundFileStream::OnSoundEvent(int evt)
{
wxUint32 len = m_codec.GetBestSize();
while (!m_sndio->QueueFilled()) {
switch(evt) {
case wxSOUND_INPUT:
- if (len > m_len)
- len = m_len;
+ if (len > m_bytes_left)
+ len = m_bytes_left;
len = m_codec.Read(buffer, len).GetLastAccess();
PutData(buffer, len);
- m_len -= len;
- if (m_len == 0) {
+ m_bytes_left -= len;
+ if (m_bytes_left == 0) {
Stop();
delete[] buffer;
return;
}
break;
case wxSOUND_OUTPUT:
+ if (len > m_bytes_left)
+ len = m_bytes_left;
+
len = GetData(buffer, len);
- if (len == 0) {
+ m_bytes_left -= len;
+ if (m_bytes_left == 0) {
Stop();
delete[] buffer;
return;
bool StartProduction(int evt);
bool StopProduction();
- unsigned long GetLength() const;
+ wxUint32 GetLength();
+ wxUint32 GetPosition();
wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len);
wxOutputStream *m_output;
wxSoundFileState m_state, m_oldstate;
- wxUint32 m_len;
+ wxUint32 m_length, m_bytes_left;
+ bool m_prepared;
protected:
virtual bool PrepareToPlay() = 0;
virtual bool PrepareToRecord(unsigned long time) = 0;
virtual bool FinishRecording() = 0;
+ void FinishPreparation(wxUint32 len);
virtual wxUint32 GetData(void *buffer, wxUint32 len) = 0;
virtual wxUint32 PutData(const void *buffer, wxUint32 len) = 0;
}
case DATA_SIGNATURE: // "data"
end_headers = TRUE;
+ FinishPreparation(len);
break;
default:
m_input->SeekI(len, wxFromCurrent);
// We can't but there is no error.
return TRUE;
- if (m_len == 0)
+ if (m_bytes_left == 0)
return TRUE;
-
-
// TODO: Update headers when we stop before the specified time (if possible)
return TRUE;
}