Files
itgmania212121/stepmania/src/arch/Sound/RageSoundDriver_QT.cpp
T

216 lines
5.5 KiB
C++
Raw Normal View History

2003-06-24 08:44:02 +00:00
/*
* RageSoundDriver_QT.cpp
* stepmania
*
* Created by Steve Checkoway on Mon Jun 23 2003.
* Copyright (c) 2003 Steve Checkoway. All rights reserved.
*
*/
#include "global.h"
#include "RageSoundDriver_QT.h"
#include "RageLog.h"
#include "RageUtil.h"
#include "RageLog.h"
#include <QuickTime/QuickTime.h>
#include <stdlib.h>
/* Ugh */
using namespace QT;
const unsigned channels = 2;
const unsigned samplesize = channels*16;
const unsigned samples = 512;
const unsigned freq = 44100;
2003-06-24 08:44:02 +00:00
const unsigned buffersize = samples*samplesize/8;
/* Oh boy! dealing with memory at inturupt time. What fun! */
2003-06-24 08:44:02 +00:00
#pragma options align=power
static volatile Uint32 fill_me = 0;
static UInt8 *buffer[2];
static CmpSoundHeader header;
2003-06-24 08:44:02 +00:00
RageSound_QT::RageSound_QT() {
RageException::ThrowNonfatal("Class not finished!");
/*SndCallBackUPP callback;
callback = NewSndCallBackUPP(GetData);
memset(&header, 0, sizeof(header));
header.numChannels = channels;
header.sampleSize = samplesize / channels;
header.sampleRate = rate44khz; /* really 44.1kHz * /
header.numFrames = samples;
header.encode = cmpSH;
buffer[0] = new Uint8[buffersize];
buffer[1] = new Uint8[buffersize];
memset(buffer[0], 0, buffersize);
memset(buffer[1], 0, buffersize);
channel = new SndChannel;
channel->userInfo = reinterpret_cast<long>(this);
channel->qLength = 2;
soundOutput = OpenDefaultComponent(kSoundOutputDeviceType, NULL);
ASSERT(soundOutput != NULL);
TimeRecord record;
SoundComponentGetInfo(soundOutput, NULL, siOutputLatency, &record);
latency = record.value.lo / record.scale;
latency += samples / freq; /* double buffer * /
2003-06-24 08:44:02 +00:00
OSErr err = SndNewChannel(&channel, sampledSynth, initStereo, callback);
if (err != noErr) {
delete channel;
channel = NULL;
RageException::ThrowNonfatal("Unable to create audio channel");
}
2003-06-24 08:44:02 +00:00
SndCommand cmd;
cmd.cmd = clockComponentCmd;
cmd.param1 = true;
cmd.param2 = 0;
err |= SndDoImmediate(channel, &cmd);
2003-06-24 08:44:02 +00:00
cmd.cmd = getClockComponentCmd;
cmd.param1 = 0;
cmd.param2 = reinterpret_cast<long>(&clock);
err |= SndDoImmediate(channel, &cmd);
last_pos = 0;
2003-06-24 08:44:02 +00:00
cmd.cmd = callBackCmd;
cmd.param2 = 0;
err |= SndDoCommand(channel, &cmd, false);
2003-06-24 08:44:02 +00:00
if (err != noErr)
RageException::ThrowNonfatal("Unable to create audio channel");*/
2003-06-24 08:44:02 +00:00
}
RageSound_QT::~RageSound_QT() {
/*if (channel)
SndDisposeChannel(channel, true);
SAFE_DELETE_ARRAY(buffer[0]);
SAFE_DELETE_ARRAY(buffer[1]);
if (soundOutput)
CloseComponent(soundOutput);*/
2003-06-24 08:44:02 +00:00
}
void RageSound_QT::GetData(SndChannel *chan, SndCommand *cmd_passed) {
/*while (!SOUNDMAN)
SDL_Delay(10);
LockMutex L(SOUNDMAN->lock);
static bool gettingData=false;
static int recursiveCalls = 0;
if (gettingData) {
LOG->Warn( "GetData() called recursively %D times.", ++recursiveCalls);
if (recursiveCalls >=10)
RageException::Throw("GetData() called recursively too many times.");
} else
recursiveCalls = 0;
gettingData = true;
static SoundMixBuffer mix;
RageSound_QT *P = reinterpret_cast<RageSound_QT *>(chan->userInfo);
fill_me = cmd_passed->param2;
UInt32 play_me = !fill_me;
if (!P->last_pos){
TimeRecord tr;
ClockGetTime(P->clock, &tr);
UInt64 temp = tr.value.hi;
temp <<= 32;
temp |= tr.value.lo;
double d = static_cast<double>(temp)/tr.scale*freq;
temp = static_cast<UInt64>(d);
P->last_pos = static_cast<UInt32>(temp % 0x00000000FFFFFFFFLL);
} else
P->last_pos += samples;
/* Swap buffers * /
header.samplePtr = reinterpret_cast<Ptr>(buffer[play_me]);
SndCommand cmd;
cmd.cmd = bufferCmd;
cmd.param1 = 0;
cmd.param2 = reinterpret_cast<long>(&header);
SndDoCommand(chan, &cmd, 0);
2003-06-24 08:44:02 +00:00
/* Clear the fill buffer * /
memset(buffer[fill_me], 0, buffersize);
2003-06-24 08:44:02 +00:00
for (unsigned i=0; i<P->sounds.size(); ++i) {
if (P->sounds[i]->stopping)
continue;
unsigned got = P->sounds[i]->snd->GetPCM(reinterpret_cast<char *>(buffer[fill_me]), buffersize, P->last_pos);
mix.write(reinterpret_cast<SInt16 *>(buffer[fill_me]), got / 2);
if (got < buffersize) {
P->sounds[i]->stopping = true;
P->sounds[i]->flush_pos = P->last_pos + (got * 8 / samplesize);
}
}
2003-06-24 08:44:02 +00:00
mix.read(reinterpret_cast<SInt16 *>(buffer[fill_me]));
cmd.cmd = callBackCmd;
cmd.param2 = play_me;
SndDoCommand(chan, &cmd, 0);
gettingData=false;*/
2003-06-24 08:44:02 +00:00
}
void RageSound_QT::StartMixing(RageSound *snd) {
/*sound *s = new sound;
s->snd = snd;
LockMutex L(SOUNDMAN->lock);
sounds.push_back(s);
LOG->Trace("There are %D sounds playing", sounds.size());*/
2003-06-24 08:44:02 +00:00
}
void RageSound_QT::StopMixing(RageSound *snd) {
/*LockMutex L(SOUNDMAN->lock);
2003-06-24 08:44:02 +00:00
/* Find the sound. * /
unsigned i;
for(i = 0; i < sounds.size(); ++i)
if(sounds[i]->snd == snd) break;
if(i == sounds.size())
{
LOG->Trace("not stopping a sound because it's not playing");
return;
}
2003-06-24 08:44:02 +00:00
delete sounds[i];
sounds.erase(sounds.begin()+i, sounds.begin()+i+1);
LOG->Trace("There are %D sounds playing", sounds.size());*/
2003-06-24 08:44:02 +00:00
}
void RageSound_QT::Update(float delta) {
#pragma unused (delta)
/*LockMutex L(SOUNDMAN->lock);
2003-06-24 08:44:02 +00:00
vector<sound *>snds = sounds;
for (unsigned i = 0; i < snds.size(); ++i) {
if (!sounds[i]->stopping)
continue;
if (GetPosition(snds[i]->snd) < sounds[i]->flush_pos)
continue;
snds[i]->snd->StopPlaying();
}*/
2003-06-24 08:44:02 +00:00
}
int RageSound_QT::GetPosition(const RageSound *snd) const {
#pragma unused (snd)
/*TimeRecord tr;
ClockGetTime(clock, &tr);
UInt64 temp = tr.value.hi;
temp <<= 32;
temp |= tr.value.lo;
double d = static_cast<double>(temp)/tr.scale*freq;
temp = static_cast<UInt64>(d);
return static_cast<UInt32>(temp % 0x00000000FFFFFFFFLL);*/
2003-06-24 08:44:02 +00:00
}
float RageSound_QT::GetPlayLatency() const {
//return latency;
2003-06-24 08:44:02 +00:00
}