Files
haiku-beta6/src/kits/game/SimpleGameSound.cpp
T

397 lines
7.3 KiB
C++
Raw Normal View History

2007-04-14 13:35:39 +00:00
/*
* Copyright 2001-2005, Haiku Inc.
* Authors:
* Christopher ML Zumwalt May ([email protected])
*
* Distributed under the terms of the MIT License.
*/
#include <stdlib.h>
#include <string.h>
#include <Entry.h>
#include <MediaFile.h>
#include <MediaTrack.h>
2002-08-11 00:34:01 +00:00
2002-10-21 16:53:45 +00:00
#include "GameSoundDefs.h"
#include "GameSoundBuffer.h"
#include "GameSoundDevice.h"
#include "GSUtility.h"
2002-08-11 00:34:01 +00:00
#include <SimpleGameSound.h>
2007-04-12 19:20:45 +00:00
BSimpleGameSound::BSimpleGameSound(const entry_ref *inFile, BGameSoundDevice *device)
: BGameSound(device)
2002-08-11 00:34:01 +00:00
{
if (InitCheck() == B_OK)
SetInitError(Init(inFile));
2002-08-11 00:34:01 +00:00
}
2007-04-12 19:20:45 +00:00
BSimpleGameSound::BSimpleGameSound(const char *inFile, BGameSoundDevice *device)
: BGameSound(device)
2002-08-11 00:34:01 +00:00
{
if (InitCheck() == B_OK)
{
entry_ref file;
if (get_ref_for_path(inFile, &file) != B_OK)
SetInitError(B_ENTRY_NOT_FOUND);
else
SetInitError(Init(&file));
}
2002-08-11 00:34:01 +00:00
}
BSimpleGameSound::BSimpleGameSound(const void *inData,
size_t inFrameCount,
const gs_audio_format *format,
BGameSoundDevice *device)
: BGameSound(device)
2002-08-11 00:34:01 +00:00
{
if (InitCheck() == B_OK)
2007-04-12 19:20:45 +00:00
SetInitError(Init(inData, inFrameCount, format));
2002-08-11 00:34:01 +00:00
}
BSimpleGameSound::BSimpleGameSound(const BSimpleGameSound &other)
: BGameSound(other)
{
gs_audio_format format;
2005-06-08 01:23:44 +00:00
void *data = NULL;
status_t error = other.Device()->Buffer(other.ID(), &format, data);
2005-06-08 01:23:44 +00:00
if (error != B_OK)
SetInitError(error);
Init(data, 0, &format);
free(data);
2002-08-11 00:34:01 +00:00
}
2005-06-08 01:23:44 +00:00
2002-08-11 00:34:01 +00:00
BSimpleGameSound::~BSimpleGameSound()
{
}
BGameSound *
BSimpleGameSound::Clone() const
{
gs_audio_format format;
2005-06-08 01:23:44 +00:00
void *data = NULL;
status_t error = Device()->Buffer(ID(), &format, data);
2005-06-08 01:23:44 +00:00
if (error != B_OK)
return NULL;
BSimpleGameSound *clone = new BSimpleGameSound(data, 0, &format, Device());
free(data);
2005-06-08 01:23:44 +00:00
return clone;
2002-08-11 00:34:01 +00:00
}
2002-10-25 13:23:24 +00:00
/* virtual */ status_t
BSimpleGameSound::Perform(int32 selector, void * data)
{
return B_ERROR;
}
2002-08-11 00:34:01 +00:00
status_t
BSimpleGameSound::SetIsLooping(bool looping)
2002-08-11 00:34:01 +00:00
{
gs_attribute attribute;
attribute.attribute = B_GS_LOOPING;
attribute.value = (looping) ? -1.0 : 0.0;
attribute.duration = bigtime_t(0);
attribute.flags = 0;
return Device()->SetAttributes(ID(), &attribute, 1);
2002-08-11 00:34:01 +00:00
}
bool
BSimpleGameSound::IsLooping() const
{
gs_attribute attribute;
attribute.attribute = B_GS_LOOPING;
attribute.flags = 0;
if (Device()->GetAttributes(ID(), &attribute, 1) != B_OK)
return false;
return bool(attribute.value);
}
status_t
BSimpleGameSound::Init(const entry_ref* inFile)
{
BMediaFile file(inFile);
gs_audio_format gsformat;
media_format mformat;
int64 framesRead, framesTotal = 0;
2007-04-12 19:20:45 +00:00
if (file.InitCheck() != B_OK)
return file.InitCheck();
BMediaTrack* audioStream = file.TrackAt(0);
audioStream->EncodedFormat(&mformat);
2007-04-12 19:20:45 +00:00
if (!mformat.IsAudio())
return B_ERROR;
int64 frames = audioStream->CountFrames();
memset(&mformat, 0, sizeof(media_format));
mformat.type = B_MEDIA_RAW_AUDIO;
2002-10-21 16:53:45 +00:00
// mformat.u.raw_audio.byte_order = (B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN;
status_t error = audioStream->DecodedFormat(&mformat);
if (error != B_OK) return error;
memset(&gsformat, 0, sizeof(gs_audio_format));
2002-10-21 16:53:45 +00:00
media_to_gs_format(&gsformat, &mformat.u.raw_audio);
2007-04-12 19:20:45 +00:00
if (mformat.u.raw_audio.format == media_raw_audio_format::B_AUDIO_CHAR) {
// The GameKit doesnt support this format so we will have to reformat
// the data into something the GameKit does support.
char * buffer = new char[gsformat.buffer_size];
uchar * data = new uchar[frames * gsformat.channel_count];
2007-04-12 19:20:45 +00:00
while (framesTotal < frames) {
// read the next chunck from the stream
memset(buffer, 0, gsformat.buffer_size);
audioStream->ReadFrames(buffer, &framesRead);
// refomat the buffer from
int64 position = framesTotal * gsformat.channel_count;
for(int32 i = 0; i < (int32)gsformat.buffer_size; i++)
data[i + position] = buffer[i] + 128;
framesTotal += framesRead;
}
gsformat.format = gs_audio_format::B_GS_U8;
2002-10-21 16:53:45 +00:00
error = Init(data, frames, &gsformat);
// free the buffers we no longer need
delete [] buffer;
delete [] data;
2007-04-12 19:20:45 +00:00
} else {
2002-10-21 16:53:45 +00:00
// We need to detriman the size, in bytes, of a single sample.
// At the same time, we will store the format of the audio buffer
size_t frameSize = get_sample_size(gsformat.format) * gsformat.channel_count;
char * data = new char[frames * frameSize];
gsformat.buffer_size = frames * frameSize;
2007-04-12 19:20:45 +00:00
while(framesTotal < frames) {
2002-10-21 16:53:45 +00:00
char * position = &data[framesTotal * frameSize];
audioStream->ReadFrames(position, &framesRead);
2002-10-21 16:53:45 +00:00
framesTotal += framesRead;
}
2002-10-21 16:53:45 +00:00
error = Init(data, frames, &gsformat);
2002-10-21 16:53:45 +00:00
delete [] data;
}
file.ReleaseTrack(audioStream);
2002-10-21 16:53:45 +00:00
return error;
}
2002-08-11 00:34:01 +00:00
status_t
2007-04-12 19:20:45 +00:00
BSimpleGameSound::Init(const void* inData, int64 inFrameCount,
const gs_audio_format* format)
2002-08-11 00:34:01 +00:00
{
gs_id sound;
status_t error = Device()->CreateBuffer(&sound, format, inData, inFrameCount);
2007-04-12 19:20:45 +00:00
if (error != B_OK)
return error;
BGameSound::Init(sound);
return B_OK;
2002-08-11 00:34:01 +00:00
}
/* unimplemented for protection of the user:
*
* BSimpleGameSound::BSimpleGameSound()
* BSimpleGameSound &BSimpleGameSound::operator=(const BSimpleGameSound &)
*/
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_0(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_1(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_2(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_3(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_4(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_5(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_6(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_7(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_8(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_9(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_10(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_11(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_12(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_13(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_14(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_15(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_16(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_17(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_18(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_19(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_20(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_21(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_22(int32 arg, ...)
{
return B_ERROR;
}
status_t
BSimpleGameSound::_Reserved_BSimpleGameSound_23(int32 arg, ...)
{
return B_ERROR;
}