wxWidgets/utils/wxMMedia/sndpcm.cpp

210 lines
4.5 KiB
C++
Raw Normal View History

////////////////////////////////////////////////////////////////////////////////
// Name: sndpcm.cpp
// Purpose: wxMMedia
// Author: Guilhem Lavaux
// Created: 1998
// Updated: 1999
// Copyright: (C) 1997, 1998, 1999, Guilhem Lavaux
// License: wxWindows license
////////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "sndpcm.h"
#endif
#include "sndsnd.h"
#include "sndpcm.h"
#define WX_BIG_ENDIAN 0
wxSoundPcmCodec::wxSoundPcmCodec()
: wxSoundCodec()
{
m_orig_format.SetCodecCreate(FALSE);
m_orig_format.SetCodecNo(WXSOUND_PCM);
}
wxSoundPcmCodec::~wxSoundPcmCodec()
{
}
size_t wxSoundPcmCodec::GetByteRate() const
{
return (m_orig_format.GetBps()/8)*
m_orig_format.GetSampleRate()*
m_orig_format.GetChannels();
}
wxSoundDataFormat wxSoundPcmCodec::GetPreferredFormat(int codec) const
{
wxSoundDataFormat prefFormat;
prefFormat = m_orig_format;
return prefFormat;
}
// ---------------------------------------------------------------------------
// Main part of the decoder
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::Decode()
{
if (m_io_format == m_orig_format) {
CopyToOutput();
return;
}
// Swap bytes
switch (m_io_format.GetBps()) {
case 8:
InputSign8();
break;
case 16:
InputSwapAndSign16();
break;
case 32:
case 64:
default:
break;
}
}
// ---------------------------------------------------------------------------
// Change the sign of a 8-bit sample.
#define GET() (m_in_sound->GetChar())
#define PUT(c) (m_out_sound->PutChar(c))
void wxSoundPcmCodec::InputSign8()
{
unsigned char signer = 0;
if (m_io_format.GetSign() != m_orig_format.GetSign())
signer = 128;
while (StreamOk())
PUT(GET() + signer);
}
// ---------------------------------------------------------------------------
// Swap bytes and change the sign of a 16-bit sample.
void wxSoundPcmCodec::InputSwapAndSign16()
{
unsigned short signer1 = 0, signer2 = 0;
bool swap = (m_io_format.GetByteOrder() != m_orig_format.GetByteOrder());
register char temp, temp2;
if (m_io_format.GetSign() != m_orig_format.GetSign()) {
if (m_io_format.GetByteOrder() == wxSND_SAMPLE_LE)
signer2 = 0x80;
else
signer1 = 0x80;
}
if (swap) {
while (StreamOk()) {
temp = GET();
temp2 = GET();
PUT(temp2 ^ signer2);
if (!StreamOk()) {
m_in_sound->WriteBack(temp);
m_in_sound->WriteBack(temp2);
break;
}
PUT(temp ^ signer1);
}
} else {
while (StreamOk()) {
temp = GET();
temp2 = GET();
PUT(temp ^ signer1);
if (!StreamOk()) {
m_in_sound->WriteBack(temp);
m_in_sound->WriteBack(temp2);
break;
}
PUT(GET() ^ signer2);
}
}
}
// ---------------------------------------------------------------------------
// Encoder part.
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::OutputSign8()
{
unsigned char signer = 0;
if (m_io_format.GetSign() != m_orig_format.GetSign())
signer = 128;
while (StreamOk())
PUT((char)(GET() + signer));
}
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::OutputSwapAndSign16()
{
bool swap = (m_io_format.GetByteOrder() != m_orig_format.GetByteOrder());
unsigned short signer1 = 0, signer2 = 0;
register char temp, temp2;
if (m_io_format.GetSign() != m_orig_format.GetSign())
if (m_io_format.GetByteOrder() == wxSND_SAMPLE_LE)
signer1 = 0x80;
else
signer2 = 0x80;
if (swap) {
while (StreamOk()) {
temp = GET();
temp2 = GET();
PUT(temp2 ^ signer1);
if (!StreamOk()) {
m_in_sound->WriteBack(temp);
m_in_sound->WriteBack(temp2);
break;
}
PUT(temp ^ signer2);
}
} else {
while (StreamOk()) {
temp = GET();
temp2 = GET();
PUT(temp ^ signer1);
if (!StreamOk()) {
m_in_sound->WriteBack(temp);
m_in_sound->WriteBack(temp2);
break;
}
PUT(temp2 ^ signer2);
}
}
}
// ---------------------------------------------------------------------------
void wxSoundPcmCodec::Encode()
{
if (m_io_format == m_orig_format) {
CopyToOutput();
return;
}
// Swap bytes
switch (m_io_format.GetBps()) {
case 8:
OutputSign8();
break;
case 16:
OutputSwapAndSign16();
break;
case 32:
case 64:
default:
break;
}
}