Decouple <cstdint>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "ALSA9Dynamic.h"
|
||||
#include "PrefsManager.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
@@ -90,7 +91,7 @@ bool Alsa9Buf::SetSWParams()
|
||||
/* If this fails, we might have bound dsnd_pcm_sw_params_set_avail_min to
|
||||
* the old SW API. */
|
||||
// ASSERT( err <= 0 );
|
||||
|
||||
|
||||
/* Disable SND_PCM_STATE_XRUN. */
|
||||
snd_pcm_uframes_t boundary = 0;
|
||||
err = dsnd_pcm_sw_params_get_boundary( swparams, &boundary );
|
||||
@@ -138,7 +139,7 @@ static RString DeviceName()
|
||||
|
||||
void Alsa9Buf::GetSoundCardDebugInfo()
|
||||
{
|
||||
static bool done = false;
|
||||
static bool done = false;
|
||||
if( done )
|
||||
return;
|
||||
done = true;
|
||||
@@ -204,7 +205,7 @@ void Alsa9Buf::GetSoundCardDebugInfo()
|
||||
|
||||
if( card == 0 )
|
||||
LOG->Info( "No ALSA sound cards were found.");
|
||||
|
||||
|
||||
if( !PREFSMAN->m_iSoundDevice.Get().empty() )
|
||||
LOG->Info( "ALSA device overridden to \"%s\"", PREFSMAN->m_iSoundDevice.Get().c_str() );
|
||||
}
|
||||
@@ -231,11 +232,11 @@ RString Alsa9Buf::Init( int channels_,
|
||||
samplerate = 44100;
|
||||
else
|
||||
samplerate = iSampleRate;
|
||||
|
||||
|
||||
GetSoundCardDebugInfo();
|
||||
|
||||
|
||||
InitializeErrorHandler();
|
||||
|
||||
|
||||
/* Open the device. */
|
||||
int err;
|
||||
err = dsnd_pcm_open( &pcm, DeviceName(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK );
|
||||
@@ -277,7 +278,7 @@ int Alsa9Buf::GetNumFramesToFill()
|
||||
int ActualWriteahead = std::max( writeahead, chunksize*2 );
|
||||
|
||||
snd_pcm_sframes_t avail_frames = dsnd_pcm_avail_update(pcm);
|
||||
|
||||
|
||||
int total_frames = writeahead;
|
||||
if( avail_frames > total_frames )
|
||||
{
|
||||
@@ -297,7 +298,7 @@ int Alsa9Buf::GetNumFramesToFill()
|
||||
dsnd_pcm_forward( pcm, size );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( avail_frames < 0 )
|
||||
avail_frames = dsnd_pcm_avail_update(pcm);
|
||||
|
||||
@@ -336,7 +337,7 @@ bool Alsa9Buf::WaitUntilFramesCanBeFilled( int timeout_ms )
|
||||
return err == 1;
|
||||
}
|
||||
|
||||
void Alsa9Buf::Write( const int16_t *buffer, int frames )
|
||||
void Alsa9Buf::Write( const std::int16_t *buffer, int frames )
|
||||
{
|
||||
/* We should be able to write it all. If we don't, treat it as an error. */
|
||||
int wrote;
|
||||
@@ -387,7 +388,7 @@ bool Alsa9Buf::Recover( int r )
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t Alsa9Buf::GetPosition() const
|
||||
std::int64_t Alsa9Buf::GetPosition() const
|
||||
{
|
||||
if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED )
|
||||
return last_cursor_pos;
|
||||
@@ -420,7 +421,7 @@ RString Alsa9Buf::GetHardwareID( RString name )
|
||||
|
||||
if( name.empty() )
|
||||
name = DeviceName();
|
||||
|
||||
|
||||
snd_ctl_t *handle;
|
||||
int err;
|
||||
err = dsnd_ctl_open( &handle, name, 0 );
|
||||
@@ -443,7 +444,7 @@ RString Alsa9Buf::GetHardwareID( RString name )
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -453,7 +454,7 @@ RString Alsa9Buf::GetHardwareID( RString name )
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef ALSA9_HELPERS_H
|
||||
#define ALSA9_HELPERS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#define ALSA_PCM_NEW_HW_PARAMS_API
|
||||
#define ALSA_PCM_NEW_SW_PARAMS_API
|
||||
#include <alsa/asoundlib.h>
|
||||
@@ -11,7 +13,7 @@ private:
|
||||
int channels, samplebits;
|
||||
unsigned samplerate;
|
||||
int buffersize;
|
||||
int64_t last_cursor_pos;
|
||||
std::int64_t last_cursor_pos;
|
||||
|
||||
snd_pcm_uframes_t preferred_writeahead, preferred_chunksize;
|
||||
snd_pcm_uframes_t writeahead, chunksize;
|
||||
@@ -23,37 +25,37 @@ private:
|
||||
bool SetSWParams();
|
||||
|
||||
static void ErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...);
|
||||
|
||||
|
||||
public:
|
||||
static void InitializeErrorHandler();
|
||||
static void GetSoundCardDebugInfo();
|
||||
static RString GetHardwareID( RString name="" );
|
||||
|
||||
|
||||
Alsa9Buf();
|
||||
RString Init( int channels,
|
||||
int iWriteahead,
|
||||
int iChunkSize,
|
||||
int iSampleRate );
|
||||
~Alsa9Buf();
|
||||
|
||||
|
||||
int GetNumFramesToFill();
|
||||
bool WaitUntilFramesCanBeFilled( int timeout_ms );
|
||||
void Write( const int16_t *buffer, int frames );
|
||||
|
||||
void Write( const std::int16_t *buffer, int frames );
|
||||
|
||||
void Play();
|
||||
void Stop();
|
||||
void SetVolume(float vol);
|
||||
int GetSampleRate() const { return samplerate; }
|
||||
|
||||
int64_t GetPosition() const;
|
||||
int64_t GetPlayPos() const { return last_cursor_pos; }
|
||||
std::int64_t GetPosition() const;
|
||||
std::int64_t GetPlayPos() const { return last_cursor_pos; }
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -63,7 +65,7 @@ public:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "archutils/Win32/GetFileInformation.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(_WINDOWS)
|
||||
#include <mmsystem.h>
|
||||
@@ -558,7 +559,7 @@ void DSoundBuf::release_output_buf( char *pBuffer, unsigned iBufferSize )
|
||||
m_bBufferLocked = false;
|
||||
}
|
||||
|
||||
int64_t DSoundBuf::GetPosition() const
|
||||
std::int64_t DSoundBuf::GetPosition() const
|
||||
{
|
||||
DWORD iCursor, iJunk;
|
||||
HRESULT hr = m_pBuffer->GetCurrentPosition( &iCursor, &iJunk );
|
||||
@@ -588,7 +589,7 @@ int64_t DSoundBuf::GetPosition() const
|
||||
if( iFramesBehind < 0 )
|
||||
iFramesBehind += buffersize_frames(); /* unwrap */
|
||||
|
||||
int64_t iRet = m_iWriteCursorPos - iFramesBehind;
|
||||
std::int64_t iRet = m_iWriteCursorPos - iFramesBehind;
|
||||
|
||||
/* Failsafe: never return a value smaller than we've already returned.
|
||||
* This can happen once in a while in underrun conditions. */
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef DSOUND_HELPERS
|
||||
#define DSOUND_HELPERS 1
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <wtypes.h>
|
||||
@@ -36,7 +38,7 @@ public:
|
||||
enum { DYNAMIC_SAMPLERATE = -1 };
|
||||
|
||||
DSoundBuf();
|
||||
RString Init( DSound &ds, hw hardware,
|
||||
RString Init( DSound &ds, hw hardware,
|
||||
int iChannels, int iSampleRate, int iSampleBits, int iWriteAhead );
|
||||
|
||||
bool get_output_buf( char **pBuffer, unsigned *iBuffersize, int iChunksize );
|
||||
@@ -49,8 +51,8 @@ public:
|
||||
int GetSampleRate() const { return m_iSampleRate; }
|
||||
|
||||
~DSoundBuf();
|
||||
int64_t GetPosition() const;
|
||||
int64_t GetOutputPosition() const { return m_iWriteCursorPos; }
|
||||
std::int64_t GetPosition() const;
|
||||
std::int64_t GetOutputPosition() const { return m_iWriteCursorPos; }
|
||||
|
||||
private:
|
||||
int buffersize_frames() const { return m_iBufferSize / bytes_per_frame(); }
|
||||
@@ -65,11 +67,11 @@ private:
|
||||
int m_iVolume;
|
||||
|
||||
int m_iBufferSize;
|
||||
|
||||
|
||||
int m_iWriteCursor, m_iBufferBytesFilled; /* bytes */
|
||||
int m_iExtraWriteahead;
|
||||
int64_t m_iWriteCursorPos; /* frames */
|
||||
mutable int64_t m_iLastPosition;
|
||||
std::int64_t m_iWriteCursorPos; /* frames */
|
||||
mutable std::int64_t m_iLastPosition;
|
||||
bool m_bPlaying;
|
||||
|
||||
bool m_bBufferLocked;
|
||||
@@ -85,7 +87,7 @@ private:
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -95,7 +97,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "RageTimer.h"
|
||||
#include "RageUtil_CircularBuffer.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class RageSoundBase;
|
||||
class RageTimer;
|
||||
class RageSoundMixBuffer;
|
||||
@@ -35,7 +37,7 @@ public:
|
||||
|
||||
/* A RageSound calls this to request it not be played. When this function
|
||||
* returns, snd is no longer valid; ensure no running threads are still
|
||||
* accessing it before returning. This must handle gracefully the case where
|
||||
* accessing it before returning. This must handle gracefully the case where
|
||||
* snd was not actually being played, though it may print a warning. */
|
||||
void StopMixing( RageSoundBase *pSound );
|
||||
|
||||
@@ -48,8 +50,8 @@ public:
|
||||
|
||||
/* Get the current hardware frame position, in the same time base as passed to
|
||||
* RageSound::CommitPlayingPosition. */
|
||||
int64_t GetHardwareFrame( RageTimer *pTimer ) const;
|
||||
virtual int64_t GetPosition() const = 0;
|
||||
std::int64_t GetHardwareFrame( RageTimer *pTimer ) const;
|
||||
virtual std::int64_t GetPosition() const = 0;
|
||||
void low_sample_count_workaround();
|
||||
|
||||
/* When a sound is finished playing (GetDataToPlay returns 0) and the sound has
|
||||
@@ -77,7 +79,7 @@ protected:
|
||||
* at once. This should generally be slightly larger than the sound writeahead,
|
||||
* to allow filling the buffer after an underrun. The default is 4096 frames. */
|
||||
void SetDecodeBufferSize( int frames );
|
||||
|
||||
|
||||
/* Override this to set the priority of the decoding thread, which should be above
|
||||
* normal priority but not realtime. */
|
||||
virtual void SetupDecodingThread() { }
|
||||
@@ -95,10 +97,10 @@ protected:
|
||||
* This function only mixes data; it will not lock any mutexes or do any file access, and
|
||||
* is safe to call from a realtime thread.
|
||||
*/
|
||||
void Mix( int16_t *pBuf, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame );
|
||||
void Mix( float *pBuf, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame );
|
||||
void Mix( std::int16_t *pBuf, int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame );
|
||||
void Mix( float *pBuf, int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame );
|
||||
|
||||
void MixDeinterlaced( float **pBufs, int iChannels, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame );
|
||||
void MixDeinterlaced( float **pBufs, int iChannels, int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame );
|
||||
|
||||
private:
|
||||
/* This mutex is used for serializing with the decoder thread. Locking this mutex
|
||||
@@ -133,13 +135,13 @@ private:
|
||||
* HALTING: The main thread has called StopMixing or the data buffer is empty. The mixing
|
||||
* thread will flush any remaining buffered data without playing it, and then move the
|
||||
* sound to STOPPED.
|
||||
*
|
||||
*
|
||||
* The mixing thread operates without any locks. This can lead to a little overlap. For
|
||||
* example, if StopMixing() is called, moving the sound from PLAYING to HALTING, the mixing
|
||||
* thread might be in the middle of mixing data. Although HALTING means "discard buffered
|
||||
* data", some data will still be mixed. This is OK; the data is valid, and the flush will
|
||||
* happen on the next iteration.
|
||||
*
|
||||
*
|
||||
* The only state change made by the decoding thread is on EOF: the state is changed
|
||||
* from PLAYING to STOPPING. This is done while m_Mutex is held, to prevent
|
||||
* races with other threads.
|
||||
@@ -155,9 +157,9 @@ private:
|
||||
float m_Buffer[samples_per_block];
|
||||
float *m_BufferNext; // beginning of the unread data
|
||||
int m_FramesInBuffer; // total number of frames at m_BufferNext
|
||||
int64_t m_iPosition; // stream frame of m_BufferNext
|
||||
std::int64_t m_iPosition; // stream frame of m_BufferNext
|
||||
sound_block(): m_BufferNext(m_Buffer),
|
||||
m_FramesInBuffer(0), m_iPosition(0) {}
|
||||
m_FramesInBuffer(0), m_iPosition(0) {}
|
||||
};
|
||||
|
||||
struct Sound
|
||||
@@ -175,8 +177,8 @@ private:
|
||||
struct QueuedPosMap
|
||||
{
|
||||
int iFrames;
|
||||
int64_t iStreamFrame;
|
||||
int64_t iHardwareFrame;
|
||||
std::int64_t iStreamFrame;
|
||||
std::int64_t iHardwareFrame;
|
||||
};
|
||||
|
||||
CircBuf<QueuedPosMap> m_PosMapQueue;
|
||||
@@ -200,16 +202,16 @@ private:
|
||||
/* List of currently playing sounds: XXX no vector */
|
||||
Sound m_Sounds[32];
|
||||
|
||||
int64_t ClampHardwareFrame( int64_t iHardwareFrame ) const;
|
||||
mutable int64_t m_iMaxHardwareFrame;
|
||||
mutable int64_t m_iVMaxHardwareFrame;
|
||||
mutable int32_t soundDriverMaxSamples = 0;
|
||||
std::int64_t ClampHardwareFrame( std::int64_t iHardwareFrame ) const;
|
||||
mutable std::int64_t m_iMaxHardwareFrame;
|
||||
mutable std::int64_t m_iVMaxHardwareFrame;
|
||||
mutable std::int32_t soundDriverMaxSamples = 0;
|
||||
|
||||
bool m_bShutdownDecodeThread;
|
||||
|
||||
static int DecodeThread_start( void *p );
|
||||
void DecodeThread();
|
||||
RageSoundMixBuffer &MixIntoBuffer( int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame );
|
||||
RageSoundMixBuffer &MixIntoBuffer( int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame );
|
||||
RageThread m_DecodeThread;
|
||||
|
||||
int GetDataForSound( Sound &s );
|
||||
@@ -224,7 +226,7 @@ private:
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -234,7 +236,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "archutils/Unix/GetSysInfo.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
@@ -18,7 +19,7 @@ REGISTER_SOUND_DRIVER_CLASS2( ALSA-sw, ALSA9_Software );
|
||||
|
||||
static const int channels = 2;
|
||||
static const int samples_per_frame = channels;
|
||||
static const int bytes_per_frame = sizeof(int16_t) * samples_per_frame;
|
||||
static const int bytes_per_frame = sizeof(std::int16_t) * samples_per_frame;
|
||||
|
||||
/* Linux 2.6 has a fine-grained scheduler. We can almost always use a smaller buffer
|
||||
* size than in 2.4. XXX: Some cards can handle smaller buffer sizes than others. */
|
||||
@@ -53,7 +54,7 @@ bool RageSoundDriver_ALSA9_Software::GetData()
|
||||
if( frames_to_fill <= 0 )
|
||||
return false;
|
||||
|
||||
static int16_t *buf = nullptr;
|
||||
static std::int16_t *buf = nullptr;
|
||||
static int bufsize = 0;
|
||||
if( buf && bufsize < frames_to_fill )
|
||||
{
|
||||
@@ -62,12 +63,12 @@ bool RageSoundDriver_ALSA9_Software::GetData()
|
||||
}
|
||||
if( !buf )
|
||||
{
|
||||
buf = new int16_t[frames_to_fill*samples_per_frame];
|
||||
buf = new std::int16_t[frames_to_fill*samples_per_frame];
|
||||
bufsize = frames_to_fill;
|
||||
}
|
||||
|
||||
const int64_t play_pos = m_pPCM->GetPlayPos();
|
||||
const int64_t cur_play_pos = m_pPCM->GetPosition();
|
||||
const std::int64_t play_pos = m_pPCM->GetPlayPos();
|
||||
const std::int64_t cur_play_pos = m_pPCM->GetPosition();
|
||||
|
||||
this->Mix( buf, frames_to_fill, play_pos, cur_play_pos );
|
||||
m_pPCM->Write( buf, frames_to_fill );
|
||||
@@ -76,10 +77,10 @@ bool RageSoundDriver_ALSA9_Software::GetData()
|
||||
}
|
||||
|
||||
|
||||
int64_t RageSoundDriver_ALSA9_Software::GetPosition() const
|
||||
std::int64_t RageSoundDriver_ALSA9_Software::GetPosition() const
|
||||
{
|
||||
return m_pPCM->GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void RageSoundDriver_ALSA9_Software::SetupDecodingThread()
|
||||
{
|
||||
@@ -119,9 +120,9 @@ RString RageSoundDriver_ALSA9_Software::Init()
|
||||
return sError;
|
||||
|
||||
m_iSampleRate = m_pPCM->GetSampleRate();
|
||||
|
||||
|
||||
StartDecodeThread();
|
||||
|
||||
|
||||
m_MixingThread.SetName( "RageSoundDriver_ALSA9_Software" );
|
||||
m_MixingThread.Create( MixerThread_start, this );
|
||||
|
||||
@@ -138,7 +139,7 @@ RageSoundDriver_ALSA9_Software::~RageSoundDriver_ALSA9_Software()
|
||||
m_MixingThread.Wait();
|
||||
LOG->Trace("Mixer thread shut down.");
|
||||
}
|
||||
|
||||
|
||||
delete m_pPCM;
|
||||
|
||||
UnloadALSA();
|
||||
@@ -152,7 +153,7 @@ float RageSoundDriver_ALSA9_Software::GetPlayLatency() const
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -162,7 +163,7 @@ float RageSoundDriver_ALSA9_Software::GetPlayLatency() const
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
#include "RageSound.h"
|
||||
#include "RageThreads.h"
|
||||
#include "RageSoundDriver.h"
|
||||
|
||||
#include "ALSA9Helpers.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class RageSoundDriver_ALSA9_Software: public RageSoundDriver
|
||||
{
|
||||
public:
|
||||
@@ -15,7 +16,7 @@ public:
|
||||
RString Init();
|
||||
|
||||
/* virtuals: */
|
||||
int64_t GetPosition() const;
|
||||
std::int64_t GetPosition() const;
|
||||
float GetPlayLatency() const;
|
||||
int GetSampleRate() const { return m_iSampleRate; }
|
||||
|
||||
@@ -37,7 +38,7 @@ private:
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -47,7 +48,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "RageSoundDriver.h"
|
||||
#include "RageThreads.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
class RageSoundDriver_AU: public RageSoundDriver
|
||||
@@ -13,11 +16,11 @@ public:
|
||||
~RageSoundDriver_AU();
|
||||
float GetPlayLatency() const;
|
||||
int GetSampleRate() const { return m_iSampleRate; }
|
||||
int64_t GetPosition() const;
|
||||
|
||||
std::int64_t GetPosition() const;
|
||||
|
||||
protected:
|
||||
void SetupDecodingThread();
|
||||
|
||||
|
||||
private:
|
||||
static OSStatus Render( void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
@@ -41,7 +44,7 @@ private:
|
||||
/*
|
||||
* (c) 2004-2006 Steve Checkoway
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -51,7 +54,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#include "RageLog.h"
|
||||
#include "PrefsManager.h"
|
||||
#include "archutils/Darwin/DarwinThreadHelpers.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioToolbox/AudioServices.h>
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
@@ -32,20 +35,20 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate )
|
||||
AudioDeviceID OutputDevice;
|
||||
OSStatus error;
|
||||
UInt32 size = sizeof( AudioDeviceID );
|
||||
|
||||
|
||||
if( (error = AudioUnitGetProperty(au, kAudioOutputUnitProperty_CurrentDevice,
|
||||
kAudioUnitScope_Global, 0, &OutputDevice, &size)) )
|
||||
{
|
||||
LOG->Warn("No output device: %s", FormatOSError(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
AudioObjectPropertyAddress RateAddr = {
|
||||
kAudioDevicePropertyNominalSampleRate,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementWildcard
|
||||
};
|
||||
|
||||
|
||||
Float64 rate = 0.0;
|
||||
size = sizeof( Float64 );
|
||||
if( (error = AudioObjectGetPropertyData(OutputDevice, &RateAddr, 0, NULL, &size, &rate)) )
|
||||
@@ -55,29 +58,29 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate )
|
||||
}
|
||||
if( rate == desiredRate )
|
||||
return;
|
||||
|
||||
|
||||
AudioObjectPropertyAddress AvailableRatesAddr = {
|
||||
kAudioDevicePropertyAvailableNominalSampleRates,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementWildcard
|
||||
};
|
||||
|
||||
|
||||
if( (error = AudioObjectGetPropertyDataSize(OutputDevice, &AvailableRatesAddr, 0, nullptr, &size)) )
|
||||
{
|
||||
LOG->Warn("Couldn't get available nominal sample rates info: %s", FormatOSError(error));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const int num = size/sizeof(AudioValueRange);
|
||||
AudioValueRange *ranges = new AudioValueRange[num];
|
||||
|
||||
|
||||
if( (error = AudioObjectGetPropertyData(OutputDevice, &AvailableRatesAddr, 0, NULL, &size, ranges)) )
|
||||
{
|
||||
LOG->Warn("Couldn't get available nominal sample rates: %s", FormatOSError(error));
|
||||
delete[] ranges;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Float64 bestRate = 0.0;
|
||||
for( int i = 0; i < num; ++i )
|
||||
{
|
||||
@@ -89,7 +92,7 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate )
|
||||
/* XXX: If the desired rate is supported by the device, then change it, if not
|
||||
* then we should select the "best" rate. I don't really know what such a best
|
||||
* rate would be. The rate closest to the desired value? A multiple of 2?
|
||||
* For now give up if the desired sample rate isn't available. */
|
||||
* For now give up if the desired sample rate isn't available. */
|
||||
}
|
||||
delete[] ranges;
|
||||
if( bestRate == 0.0 )
|
||||
@@ -104,40 +107,40 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate )
|
||||
RString RageSoundDriver_AU::Init()
|
||||
{
|
||||
AudioComponentDescription desc;
|
||||
|
||||
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
desc.componentFlags = 0;
|
||||
desc.componentFlagsMask = 0;
|
||||
|
||||
|
||||
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
|
||||
//Component comp = FindNextComponent( NULL, &desc );
|
||||
|
||||
if( comp == nullptr )
|
||||
|
||||
if( comp == nullptr )
|
||||
return "Failed to find the default output unit.";
|
||||
|
||||
|
||||
OSStatus error = AudioComponentInstanceNew( comp, &m_OutputUnit );
|
||||
|
||||
|
||||
if( error != noErr || m_OutputUnit == nullptr )
|
||||
return ssprintf("Could not open the default output unit: %s", FormatOSError(error));
|
||||
|
||||
|
||||
// Set up a callback function to generate output to the output unit
|
||||
AURenderCallbackStruct input;
|
||||
input.inputProc = Render;
|
||||
input.inputProcRefCon = this;
|
||||
|
||||
error = AudioUnitSetProperty( m_OutputUnit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
|
||||
error = AudioUnitSetProperty( m_OutputUnit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input,
|
||||
0,
|
||||
&input,
|
||||
0,
|
||||
&input,
|
||||
sizeof(input) );
|
||||
if( error != noErr )
|
||||
return ssprintf("Failed to set render callback: %s", FormatOSError(error));
|
||||
|
||||
|
||||
AudioStreamBasicDescription streamFormat;
|
||||
|
||||
|
||||
streamFormat.mSampleRate = PREFSMAN->m_iSoundPreferredSampleRate;
|
||||
streamFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
streamFormat.mFormatFlags = kFormatFlags;
|
||||
@@ -146,12 +149,12 @@ RString RageSoundDriver_AU::Init()
|
||||
streamFormat.mBytesPerFrame = kBytesPerFrame;
|
||||
streamFormat.mChannelsPerFrame = kChannelsPerFrame;
|
||||
streamFormat.mBitsPerChannel = kBitsPerChannel;
|
||||
|
||||
|
||||
if( streamFormat.mSampleRate <= 0.0 )
|
||||
streamFormat.mSampleRate = 44100.0;
|
||||
m_iSampleRate = int( streamFormat.mSampleRate );
|
||||
m_TimeScale = streamFormat.mSampleRate / AudioGetHostClockFrequency();
|
||||
|
||||
|
||||
// Try to set the hardware sample rate.
|
||||
SetSampleRate( m_OutputUnit, streamFormat.mSampleRate );
|
||||
|
||||
@@ -165,7 +168,7 @@ RString RageSoundDriver_AU::Init()
|
||||
if( error != noErr )
|
||||
return ssprintf("Failed to set AU stream format: %s", FormatOSError(error));
|
||||
UInt32 renderQuality = kRenderQuality_Max;
|
||||
|
||||
|
||||
error = AudioUnitSetProperty( m_OutputUnit,
|
||||
kAudioUnitProperty_RenderQuality,
|
||||
kAudioUnitScope_Global,
|
||||
@@ -174,11 +177,11 @@ RString RageSoundDriver_AU::Init()
|
||||
sizeof(renderQuality) );
|
||||
if( error != noErr )
|
||||
LOG->Warn("Failed to set the maximum render quality: %s", FormatOSError(error));
|
||||
|
||||
|
||||
// Initialize the AU.
|
||||
if( (error = AudioUnitInitialize(m_OutputUnit)) )
|
||||
return ssprintf("Could not initialize the AudioUnit: %s", FormatOSError(error));
|
||||
|
||||
|
||||
StartDecodeThread();
|
||||
|
||||
if( (error = AudioOutputUnitStart(m_OutputUnit)) )
|
||||
@@ -202,9 +205,9 @@ RageSoundDriver_AU::~RageSoundDriver_AU()
|
||||
delete m_pNotificationThread;
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver_AU::GetPosition() const
|
||||
std::int64_t RageSoundDriver_AU::GetPosition() const
|
||||
{
|
||||
return int64_t( m_TimeScale * AudioGetCurrentHostTime() );
|
||||
return std::int64_t( m_TimeScale * AudioGetCurrentHostTime() );
|
||||
}
|
||||
|
||||
|
||||
@@ -223,55 +226,55 @@ float RageSoundDriver_AU::GetPlayLatency() const
|
||||
AudioDeviceID OutputDevice;
|
||||
UInt32 size = sizeof( AudioDeviceID );
|
||||
Float64 sampleRate;
|
||||
|
||||
|
||||
if( (error = AudioUnitGetProperty(m_OutputUnit, kAudioOutputUnitProperty_CurrentDevice,
|
||||
kAudioUnitScope_Global, 0, &OutputDevice, &size)) )
|
||||
{
|
||||
LOG->Warn("No output device: %s", FormatOSError(error));
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
|
||||
AudioObjectPropertyAddress RateAddr = {
|
||||
kAudioDevicePropertyNominalSampleRate,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementWildcard
|
||||
};
|
||||
|
||||
|
||||
size = sizeof( Float64 );
|
||||
if( (error = AudioObjectGetPropertyData(OutputDevice, &RateAddr, 0, nullptr, &size, &sampleRate)) )
|
||||
{
|
||||
LOG->Warn("Couldn't get the device sample rate: %s", FormatOSError(error));
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
AudioObjectPropertyAddress BufferAddr = {
|
||||
kAudioDevicePropertyBufferFrameSize,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementWildcard
|
||||
};
|
||||
|
||||
|
||||
size = sizeof( UInt32 );
|
||||
if( (error = AudioObjectGetPropertyData(OutputDevice, &BufferAddr, 0, nullptr, &size, &bufferSize)) )
|
||||
{
|
||||
LOG->Warn("Couldn't determine buffer size: %s", FormatOSError(error));
|
||||
bufferSize = 0;
|
||||
}
|
||||
|
||||
|
||||
UInt32 frames;
|
||||
|
||||
|
||||
AudioObjectPropertyAddress LatencyAddr = {
|
||||
kAudioDevicePropertyLatency,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementWildcard
|
||||
};
|
||||
|
||||
|
||||
size = sizeof( UInt32 );
|
||||
if( (error = AudioObjectGetPropertyData(OutputDevice, &LatencyAddr, 0, nullptr, &size, &frames)) )
|
||||
{
|
||||
LOG->Warn("Couldn't get device latency: %s", FormatOSError(error));
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
|
||||
AudioObjectPropertyAddress SafetyAddr = {
|
||||
kAudioDevicePropertySafetyOffset,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
@@ -294,7 +297,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementWildcard
|
||||
};
|
||||
|
||||
|
||||
if( (error = AudioObjectGetPropertyDataSize(OutputDevice, &StreamsAddr, 0, nullptr, &size)) )
|
||||
{
|
||||
LOG->Warn("Device has no streams: %s", FormatOSError(error));
|
||||
@@ -314,13 +317,13 @@ float RageSoundDriver_AU::GetPlayLatency() const
|
||||
delete[] streams;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
AudioObjectPropertyAddress LatencyAddr = {
|
||||
kAudioDevicePropertyLatency,
|
||||
kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementWildcard
|
||||
};
|
||||
|
||||
|
||||
if( (error = AudioObjectGetPropertyData(streams[0], &LatencyAddr, 0, nullptr, &size, &frames)) )
|
||||
{
|
||||
LOG->Warn("Stream does not report latency: %s", FormatOSError(error));
|
||||
@@ -329,10 +332,10 @@ float RageSoundDriver_AU::GetPlayLatency() const
|
||||
delete[] streams;
|
||||
bufferSize += frames;
|
||||
} while( false );
|
||||
|
||||
|
||||
return float( bufferSize / sampleRate );
|
||||
}
|
||||
|
||||
|
||||
|
||||
OSStatus RageSoundDriver_AU::Render( void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
@@ -347,22 +350,22 @@ OSStatus RageSoundDriver_AU::Render( void *inRefCon,
|
||||
This->m_pIOThread = new RageThreadRegister( "HAL I/O thread" );
|
||||
|
||||
AudioBuffer &buf = ioData->mBuffers[0];
|
||||
int64_t now = int64_t( This->m_TimeScale * AudioGetCurrentHostTime() );
|
||||
int64_t next = int64_t( This->m_TimeScale * inTimeStamp->mHostTime );
|
||||
|
||||
std::int64_t now = std::int64_t( This->m_TimeScale * AudioGetCurrentHostTime() );
|
||||
std::int64_t next = std::int64_t( This->m_TimeScale * inTimeStamp->mHostTime );
|
||||
|
||||
This->Mix( (float *)buf.mData, inNumberFrames, next, now );
|
||||
if( unlikely(This->m_bDone) )
|
||||
{
|
||||
AudioOutputUnitStop( This->m_OutputUnit );
|
||||
This->m_Semaphore.Post();
|
||||
}
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
/*
|
||||
* (c) 2004-2007 Steve Checkoway
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -372,7 +375,7 @@ OSStatus RageSoundDriver_AU::Render( void *inRefCon,
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "PrefsManager.h"
|
||||
#include "archutils/Win32/ErrorStrings.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
REGISTER_SOUND_DRIVER_CLASS2( DirectSound-sw, DSound_Software );
|
||||
|
||||
static const int channels = 2;
|
||||
@@ -42,7 +44,7 @@ void RageSoundDriver_DSound_Software::MixerThread()
|
||||
{
|
||||
char *pLockedBuf;
|
||||
unsigned iLen;
|
||||
const int64_t iPlayPos = m_pPCM->GetOutputPosition(); /* must be called before get_output_buf */
|
||||
const std::int64_t iPlayPos = m_pPCM->GetOutputPosition(); /* must be called before get_output_buf */
|
||||
|
||||
if( !m_pPCM->get_output_buf(&pLockedBuf, &iLen, chunksize()) )
|
||||
{
|
||||
@@ -50,7 +52,7 @@ void RageSoundDriver_DSound_Software::MixerThread()
|
||||
continue;
|
||||
}
|
||||
|
||||
this->Mix( (int16_t *) pLockedBuf, iLen/bytes_per_frame, iPlayPos, m_pPCM->GetPosition() );
|
||||
this->Mix( (std::int16_t *) pLockedBuf, iLen/bytes_per_frame, iPlayPos, m_pPCM->GetPosition() );
|
||||
|
||||
m_pPCM->release_output_buf( pLockedBuf, iLen );
|
||||
}
|
||||
@@ -60,7 +62,7 @@ void RageSoundDriver_DSound_Software::MixerThread()
|
||||
m_pPCM->Stop();
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver_DSound_Software::GetPosition() const
|
||||
std::int64_t RageSoundDriver_DSound_Software::GetPosition() const
|
||||
{
|
||||
return m_pPCM->GetPosition();
|
||||
}
|
||||
@@ -146,7 +148,7 @@ int RageSoundDriver_DSound_Software::GetSampleRate() const
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -156,7 +158,7 @@ int RageSoundDriver_DSound_Software::GetSampleRate() const
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "RageThreads.h"
|
||||
#include "RageSoundDriver.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class RageSoundDriver_DSound_Software: public RageSoundDriver
|
||||
{
|
||||
public:
|
||||
@@ -12,10 +14,10 @@ public:
|
||||
virtual ~RageSoundDriver_DSound_Software();
|
||||
RString Init();
|
||||
|
||||
int64_t GetPosition() const;
|
||||
std::int64_t GetPosition() const;
|
||||
float GetPlayLatency() const;
|
||||
int GetSampleRate() const;
|
||||
|
||||
|
||||
protected:
|
||||
void SetupDecodingThread();
|
||||
|
||||
@@ -36,7 +38,7 @@ private:
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -46,7 +48,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "RageSoundReader.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
static const int channels = 2;
|
||||
|
||||
@@ -50,7 +51,7 @@ int RageSoundDriver::DecodeThread_start( void *p )
|
||||
static int g_iTotalAhead = 0;
|
||||
static int g_iTotalAheadCount = 0;
|
||||
|
||||
RageSoundMixBuffer &RageSoundDriver::MixIntoBuffer( int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame )
|
||||
RageSoundMixBuffer &RageSoundDriver::MixIntoBuffer( int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame )
|
||||
{
|
||||
ASSERT_M( m_DecodeThread.IsCreated(), "RageSoundDriver::StartDecodeThread() was never called" );
|
||||
|
||||
@@ -90,9 +91,9 @@ RageSoundMixBuffer &RageSoundDriver::MixIntoBuffer( int iFrames, int64_t iFrameN
|
||||
if( !s.m_StartTime.IsZero() && iCurrentFrame != -1 )
|
||||
{
|
||||
/* If the sound is supposed to start at a time past this buffer, insert silence. */
|
||||
const int64_t iFramesUntilThisBuffer = iFrameNumber - iCurrentFrame;
|
||||
const std::int64_t iFramesUntilThisBuffer = iFrameNumber - iCurrentFrame;
|
||||
const float fSecondsBeforeStart = -s.m_StartTime.Ago();
|
||||
const int64_t iFramesBeforeStart = int64_t(fSecondsBeforeStart * GetSampleRate());
|
||||
const std::int64_t iFramesBeforeStart = std::int64_t(fSecondsBeforeStart * GetSampleRate());
|
||||
const int iSilentFramesInThisBuffer = clamp( int(iFramesBeforeStart-iFramesUntilThisBuffer), 0, iFramesLeft );
|
||||
|
||||
iGotFrames += iSilentFramesInThisBuffer;
|
||||
@@ -160,19 +161,19 @@ RageSoundMixBuffer &RageSoundDriver::MixIntoBuffer( int iFrames, int64_t iFrameN
|
||||
return mix;
|
||||
}
|
||||
|
||||
void RageSoundDriver::Mix( int16_t *pBuf, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame )
|
||||
void RageSoundDriver::Mix( std::int16_t *pBuf, int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame )
|
||||
{
|
||||
memset( pBuf, 0, iFrames*channels*sizeof(int16_t) );
|
||||
memset( pBuf, 0, iFrames*channels*sizeof(std::int16_t) );
|
||||
MixIntoBuffer( iFrames, iFrameNumber, iCurrentFrame ).read( pBuf );
|
||||
}
|
||||
|
||||
void RageSoundDriver::Mix( float *pBuf, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame )
|
||||
void RageSoundDriver::Mix( float *pBuf, int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame )
|
||||
{
|
||||
memset( pBuf, 0, iFrames*channels*sizeof(float) );
|
||||
MixIntoBuffer( iFrames, iFrameNumber, iCurrentFrame ).read( pBuf );
|
||||
}
|
||||
|
||||
void RageSoundDriver::MixDeinterlaced( float **pBufs, int iChannels, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame )
|
||||
void RageSoundDriver::MixDeinterlaced( float **pBufs, int iChannels, int iFrames, std::int64_t iFrameNumber, std::int64_t iCurrentFrame )
|
||||
{
|
||||
for (int i = 0; i < iChannels; ++i )
|
||||
memset( pBufs[i], 0, iFrames*sizeof(float) );
|
||||
@@ -473,7 +474,7 @@ RageSoundDriver::~RageSoundDriver()
|
||||
}
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver::ClampHardwareFrame( int64_t iHardwareFrame ) const
|
||||
std::int64_t RageSoundDriver::ClampHardwareFrame( std::int64_t iHardwareFrame ) const
|
||||
{
|
||||
/* It's sometimes possible for the hardware position to move backwards, usually
|
||||
* on underrun. We can try to prevent this in each driver, but it's an obscure
|
||||
@@ -488,7 +489,7 @@ int64_t RageSoundDriver::ClampHardwareFrame( int64_t iHardwareFrame ) const
|
||||
|
||||
|
||||
//iHardwareFrame %= 0x800000; // debug test a sample value max of about 3 minutes so I dont have to spend an hour per test
|
||||
int64_t diff = iHardwareFrame - m_iMaxHardwareFrame;
|
||||
std::int64_t diff = iHardwareFrame - m_iMaxHardwareFrame;
|
||||
if( diff < 0 )
|
||||
{
|
||||
diff = 0;
|
||||
@@ -533,7 +534,7 @@ int64_t RageSoundDriver::ClampHardwareFrame( int64_t iHardwareFrame ) const
|
||||
return m_iVMaxHardwareFrame;
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver::GetHardwareFrame( RageTimer *pTimestamp=nullptr ) const
|
||||
std::int64_t RageSoundDriver::GetHardwareFrame( RageTimer *pTimestamp=nullptr ) const
|
||||
{
|
||||
if( pTimestamp == nullptr )
|
||||
return ClampHardwareFrame( GetPosition() );
|
||||
@@ -548,7 +549,7 @@ int64_t RageSoundDriver::GetHardwareFrame( RageTimer *pTimestamp=nullptr ) const
|
||||
* severe performance problems, anyway.
|
||||
*/
|
||||
int iTries = 3;
|
||||
int64_t iPositionFrames;
|
||||
std::int64_t iPositionFrames;
|
||||
do
|
||||
{
|
||||
pTimestamp->Touch();
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "PrefsManager.h"
|
||||
#include "ProductInfo.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
REGISTER_SOUND_DRIVER_CLASS( JACK );
|
||||
|
||||
RageSoundDriver_JACK::RageSoundDriver_JACK() :
|
||||
@@ -116,7 +118,7 @@ RString RageSoundDriver_JACK::ConnectPorts()
|
||||
const char **ports = nullptr;
|
||||
if( portNames.size() == 0 )
|
||||
{
|
||||
// The user has NOT specified any ports to connect to. Search
|
||||
// The user has NOT specified any ports to connect to. Search
|
||||
// for all physical sinks and use the first two.
|
||||
ports = jack_get_ports( client, nullptr, nullptr, JackPortIsInput | JackPortIsPhysical );
|
||||
if( ports == nullptr )
|
||||
@@ -137,11 +139,11 @@ RString RageSoundDriver_JACK::ConnectPorts()
|
||||
else
|
||||
{
|
||||
// The user has specified ports to connect to. Loop through
|
||||
// them to find two that are valid, then use them. If we find
|
||||
// them to find two that are valid, then use them. If we find
|
||||
// only one that is valid, connect both channels to it.
|
||||
// Use jack_port_by_name to ensure ports exist, then
|
||||
// jack_port_name to use their canonical name. (I'm not sure
|
||||
// if that second step is necessary, I've seen something about
|
||||
// jack_port_name to use their canonical name. (I'm not sure
|
||||
// if that second step is necessary, I've seen something about
|
||||
// "aliases" in the docs.)
|
||||
for ( RString const &portName : portNames )
|
||||
{
|
||||
@@ -163,12 +165,12 @@ RString RageSoundDriver_JACK::ConnectPorts()
|
||||
}
|
||||
if( port_out_l == nullptr )
|
||||
return "All specified sinks are invalid.";
|
||||
|
||||
|
||||
if( port_out_r == nullptr )
|
||||
// Only found one valid sink. Going mono!
|
||||
port_out_r = port_out_l;
|
||||
}
|
||||
|
||||
|
||||
RString ret = RString();
|
||||
|
||||
if( jack_connect( client, jack_port_name(port_l), port_out_l ) != 0 )
|
||||
@@ -182,7 +184,7 @@ RString RageSoundDriver_JACK::ConnectPorts()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver_JACK::GetPosition() const
|
||||
std::int64_t RageSoundDriver_JACK::GetPosition() const
|
||||
{
|
||||
return jack_frame_time(client);
|
||||
}
|
||||
@@ -230,7 +232,7 @@ int RageSoundDriver_JACK::SampleRateTrampoline(jack_nframes_t nframes, void *arg
|
||||
/*
|
||||
* (c) 2013 Devin J. Pohly
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -240,7 +242,7 @@ int RageSoundDriver_JACK::SampleRateTrampoline(jack_nframes_t nframes, void *arg
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#define RAGE_SOUND_JACK
|
||||
|
||||
#include "RageSoundDriver.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <jack/jack.h>
|
||||
|
||||
#define USE_RAGE_SOUND_JACK
|
||||
@@ -15,7 +18,7 @@ public:
|
||||
RString Init();
|
||||
|
||||
int GetSampleRate() const;
|
||||
int64_t GetPosition() const;
|
||||
std::int64_t GetPosition() const;
|
||||
|
||||
private:
|
||||
jack_client_t *client;
|
||||
@@ -39,7 +42,7 @@ private:
|
||||
/*
|
||||
* (c) 2013 Devin J. Pohly
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -49,7 +52,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "RageUtil.h"
|
||||
#include "PrefsManager.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
REGISTER_SOUND_DRIVER_CLASS( Null );
|
||||
|
||||
const int channels = 2;
|
||||
@@ -13,7 +15,7 @@ void RageSoundDriver_Null::Update()
|
||||
/* "Play" frames. */
|
||||
while( m_iLastCursorPos < GetPosition()+1024*4 )
|
||||
{
|
||||
int16_t buf[256*channels];
|
||||
std::int16_t buf[256*channels];
|
||||
this->Mix( buf, 256, m_iLastCursorPos, GetPosition() );
|
||||
m_iLastCursorPos += 256;
|
||||
}
|
||||
@@ -21,9 +23,9 @@ void RageSoundDriver_Null::Update()
|
||||
RageSoundDriver::Update();
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver_Null::GetPosition() const
|
||||
std::int64_t RageSoundDriver_Null::GetPosition() const
|
||||
{
|
||||
return int64_t( RageTimer::GetTimeSinceStart() * m_iSampleRate );
|
||||
return std::int64_t( RageTimer::GetTimeSinceStart() * m_iSampleRate );
|
||||
}
|
||||
|
||||
RageSoundDriver_Null::RageSoundDriver_Null()
|
||||
@@ -43,7 +45,7 @@ int RageSoundDriver_Null::GetSampleRate() const
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -53,7 +55,7 @@ int RageSoundDriver_Null::GetSampleRate() const
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -3,16 +3,18 @@
|
||||
|
||||
#include "RageSoundDriver.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class RageSoundDriver_Null: public RageSoundDriver
|
||||
{
|
||||
public:
|
||||
RageSoundDriver_Null();
|
||||
int64_t GetPosition() const;
|
||||
std::int64_t GetPosition() const;
|
||||
int GetSampleRate() const;
|
||||
void Update();
|
||||
|
||||
private:
|
||||
int64_t m_iLastCursorPos;
|
||||
std::int64_t m_iLastCursorPos;
|
||||
int m_iSampleRate;
|
||||
};
|
||||
#define USE_RAGE_SOUND_NULL
|
||||
@@ -22,7 +24,7 @@ private:
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -32,7 +34,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -5,14 +5,16 @@
|
||||
#include "RageSound.h"
|
||||
#include "RageSoundManager.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(HAVE_FCNTL_H)
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/soundcard.h>
|
||||
#include <sys/select.h>
|
||||
@@ -78,12 +80,12 @@ bool RageSoundDriver_OSS::GetData()
|
||||
|
||||
if( !ab.fragments )
|
||||
return false;
|
||||
|
||||
|
||||
const int chunksize = ab.fragsize;
|
||||
|
||||
static int16_t *buf = nullptr;
|
||||
|
||||
static std::int16_t *buf = nullptr;
|
||||
if(!buf)
|
||||
buf = new int16_t[chunksize / sizeof(int16_t)];
|
||||
buf = new std::int16_t[chunksize / sizeof(std::int16_t)];
|
||||
|
||||
this->Mix( buf, chunksize/bytes_per_frame, last_cursor_pos, GetPosition() );
|
||||
|
||||
@@ -99,10 +101,10 @@ bool RageSoundDriver_OSS::GetData()
|
||||
|
||||
/* XXX: There's a race on last_cursor_pos here: new data might be written after the
|
||||
* ioctl returns, incrementing last_cursor_pos. */
|
||||
int64_t RageSoundDriver_OSS::GetPosition() const
|
||||
std::int64_t RageSoundDriver_OSS::GetPosition() const
|
||||
{
|
||||
ASSERT( fd != -1 );
|
||||
|
||||
|
||||
int delay;
|
||||
if(ioctl(fd, SNDCTL_DSP_GETODELAY, &delay) == -1)
|
||||
FAIL_M( ssprintf("RageSoundDriver_OSS: ioctl(SNDCTL_DSP_GETODELAY): %s", strerror(errno)) );
|
||||
@@ -190,7 +192,7 @@ RString RageSoundDriver_OSS::Init()
|
||||
return ssprintf( "RageSoundDriver_OSS: ioctl(SNDCTL_DSP_CHANNELS, %i): %s", i, strerror(errno) );
|
||||
if(i != channels)
|
||||
return ssprintf( "RageSoundDriver_OSS: Wanted %i channels, got %i instead", channels, i );
|
||||
|
||||
|
||||
i = 44100;
|
||||
if(ioctl(fd, SNDCTL_DSP_SPEED, &i) == -1 )
|
||||
return ssprintf( "RageSoundDriver_OSS: ioctl(SNDCTL_DSP_SPEED, %i): %s", i, strerror(errno) );
|
||||
@@ -200,7 +202,7 @@ RString RageSoundDriver_OSS::Init()
|
||||
if(ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &i) == -1)
|
||||
return ssprintf( "RageSoundDriver_OSS: ioctl(SNDCTL_DSP_SETFRAGMENT, %i): %s", i, strerror(errno) );
|
||||
StartDecodeThread();
|
||||
|
||||
|
||||
MixingThread.SetName( "RageSoundDriver_OSS" );
|
||||
MixingThread.Create( MixerThread_start, this );
|
||||
|
||||
@@ -230,7 +232,7 @@ float RageSoundDriver_OSS::GetPlayLatency() const
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -240,7 +242,7 @@ float RageSoundDriver_OSS::GetPlayLatency() const
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "RageThreads.h"
|
||||
#include "RageTimer.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class RageSoundDriver_OSS: public RageSoundDriver
|
||||
{
|
||||
int fd;
|
||||
@@ -18,13 +20,13 @@ class RageSoundDriver_OSS: public RageSoundDriver
|
||||
RageThread MixingThread;
|
||||
|
||||
static RString CheckOSSVersion( int fd );
|
||||
|
||||
|
||||
public:
|
||||
bool GetData();
|
||||
int GetSampleRate() const { return samplerate; }
|
||||
|
||||
/* virtuals: */
|
||||
int64_t GetPosition() const;
|
||||
std::int64_t GetPosition() const;
|
||||
float GetPlayLatency() const;
|
||||
void SetupDecodingThread();
|
||||
|
||||
@@ -38,7 +40,7 @@ public:
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -48,7 +50,7 @@ public:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
/* Register the RageSoundDriver_Pulseaudio class as sound driver "Pulse" */
|
||||
REGISTER_SOUND_DRIVER_CLASS2( Pulse, PulseAudio );
|
||||
@@ -181,7 +182,7 @@ void RageSoundDriver_PulseAudio::m_InitStream(void)
|
||||
*
|
||||
* "The server tries to assure that at least tlength bytes are always
|
||||
* available in the per-stream server-side playback buffer. It is
|
||||
* recommended to set this to (uint32_t) -1, which will initialize
|
||||
* recommended to set this to (std::uint32_t) -1, which will initialize
|
||||
* this to a value that is deemed sensible by the server. However,
|
||||
* this value will default to something like 2s, i.e. for applications
|
||||
* that have specific latency requirements this value should be set to
|
||||
@@ -194,10 +195,10 @@ void RageSoundDriver_PulseAudio::m_InitStream(void)
|
||||
|
||||
/* maxlength: Maximum length of the buffer
|
||||
*
|
||||
* "Setting this to (uint32_t) -1 will initialize this to the maximum
|
||||
* "Setting this to (std::uint32_t) -1 will initialize this to the maximum
|
||||
* value supported by server, which is recommended."
|
||||
*
|
||||
* (uint32_t)-1 is NOT working here, setting it to tlength*2, like
|
||||
* (std::uint32_t)-1 is NOT working here, setting it to tlength*2, like
|
||||
* openal-soft-pulseaudio does.
|
||||
*/
|
||||
attr.maxlength = attr.tlength*2;
|
||||
@@ -206,10 +207,10 @@ void RageSoundDriver_PulseAudio::m_InitStream(void)
|
||||
*
|
||||
* "The server does not request less than minreq bytes from the client,
|
||||
* instead waits until the buffer is free enough to request more bytes
|
||||
* at once. It is recommended to set this to (uint32_t) -1, which will
|
||||
* at once. It is recommended to set this to (std::uint32_t) -1, which will
|
||||
* initialize this to a value that is deemed sensible by the server."
|
||||
*
|
||||
* (uint32_t)-1 is NOT working here, setting it to 0, like
|
||||
* (std::uint32_t)-1 is NOT working here, setting it to 0, like
|
||||
* openal-soft-pulseaudio does.
|
||||
*/
|
||||
attr.minreq = 0;
|
||||
@@ -218,10 +219,10 @@ void RageSoundDriver_PulseAudio::m_InitStream(void)
|
||||
*
|
||||
* "The server does not start with playback before at least prebuf
|
||||
* bytes are available in the buffer. It is recommended to set this
|
||||
* to (uint32_t) -1, which will initialize this to the same value as
|
||||
* to (std::uint32_t) -1, which will initialize this to the same value as
|
||||
* tlength"
|
||||
*/
|
||||
attr.prebuf = (uint32_t)-1;
|
||||
attr.prebuf = (std::uint32_t)-1;
|
||||
|
||||
/* log the used target buffer length */
|
||||
LOG->Trace("Pulse: using target buffer length of %i bytes", attr.tlength);
|
||||
@@ -300,7 +301,7 @@ void RageSoundDriver_PulseAudio::StreamStateCb(pa_stream *s)
|
||||
}
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver_PulseAudio::GetPosition() const
|
||||
std::int64_t RageSoundDriver_PulseAudio::GetPosition() const
|
||||
{
|
||||
return m_LastPosition;
|
||||
}
|
||||
@@ -317,10 +318,10 @@ void RageSoundDriver_PulseAudio::StreamWriteCb(pa_stream *s, std::size_t length)
|
||||
* maybe the requested length is given in frames instead of bytes */
|
||||
length *= 2;
|
||||
#endif
|
||||
const std::size_t nbframes = length / sizeof(int16_t); /* we use 16-bit frames */
|
||||
std::vector<int16_t> buf(nbframes);
|
||||
int64_t pos1 = m_LastPosition;
|
||||
int64_t pos2 = pos1 + nbframes/2; /* Mix() position in stereo frames */
|
||||
const std::size_t nbframes = length / sizeof(std::int16_t); /* we use 16-bit frames */
|
||||
std::vector<std::int16_t> buf(nbframes);
|
||||
std::int64_t pos1 = m_LastPosition;
|
||||
std::int64_t pos2 = pos1 + nbframes/2; /* Mix() position in stereo frames */
|
||||
this->Mix( buf.data(), pos2-pos1, pos1, pos2);
|
||||
if(pa_stream_write(m_PulseStream, buf.data(), length, nullptr, 0, PA_SEEK_RELATIVE) < 0)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "RageSoundDriver.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
@@ -17,11 +18,11 @@ public:
|
||||
|
||||
RString Init();
|
||||
|
||||
inline int64_t GetPosition() const;
|
||||
inline std::int64_t GetPosition() const;
|
||||
inline int GetSampleRate() const { return m_SampleRate; };
|
||||
|
||||
protected:
|
||||
int64_t m_LastPosition;
|
||||
std::int64_t m_LastPosition;
|
||||
int m_SampleRate;
|
||||
char *m_Error;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "archutils/Win32/ErrorStrings.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#define _INC_MMREG
|
||||
#define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */
|
||||
@@ -1022,7 +1023,7 @@ bool WinWdmStream::SubmitPacket( int iPacket, RString &sError )
|
||||
#include <windows.h>
|
||||
namespace
|
||||
{
|
||||
void MapChannels( const int16_t *pIn, int16_t *pOut, int iInChannels, int iOutChannels, int iFrames, const int *pChannelMap )
|
||||
void MapChannels( const std::int16_t *pIn, std::int16_t *pOut, int iInChannels, int iOutChannels, int iFrames, const int *pChannelMap )
|
||||
{
|
||||
for( int i = 0; i < iFrames; ++i )
|
||||
{
|
||||
@@ -1046,7 +1047,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void MapChannels( const int16_t *pIn, int16_t *pOut, int iInChannels, int iOutChannels, int iFrames )
|
||||
void MapChannels( const std::int16_t *pIn, std::int16_t *pOut, int iInChannels, int iOutChannels, int iFrames )
|
||||
{
|
||||
static const int i1ChannelMap[] = { -2 };
|
||||
static const int i4ChannelMap[] = { 0, 1, 0, 1 };
|
||||
@@ -1064,7 +1065,7 @@ namespace
|
||||
MapChannels( pIn, pOut, iInChannels, iOutChannels, iFrames, pChannelMap );
|
||||
}
|
||||
|
||||
void MapSampleFormatFromInt16( const int16_t *pIn, void *pOut, int iSamples, DeviceSampleFormat FromFormat )
|
||||
void MapSampleFormatFromInt16( const std::int16_t *pIn, void *pOut, int iSamples, DeviceSampleFormat FromFormat )
|
||||
{
|
||||
switch( FromFormat )
|
||||
{
|
||||
@@ -1089,7 +1090,7 @@ namespace
|
||||
}
|
||||
case DeviceSampleFormat_Int32:
|
||||
{
|
||||
int16_t *pOutBuf = (int16_t *) pOut;
|
||||
std::int16_t *pOutBuf = (std::int16_t *) pOut;
|
||||
for( int i = 0; i < iSamples; ++i )
|
||||
{
|
||||
*pOutBuf++ = 0;
|
||||
@@ -1109,29 +1110,29 @@ void RageSoundDriver_WDMKS::Read( void *pData, int iFrames, int iLastCursorPos,
|
||||
if( m_pStream->m_iDeviceOutputChannels == iChannels &&
|
||||
m_pStream->m_DeviceSampleFormat == DeviceSampleFormat_Int16 )
|
||||
{
|
||||
int16_t *pBuf = (int16_t *) pData;
|
||||
std::int16_t *pBuf = (std::int16_t *) pData;
|
||||
this->Mix( pBuf, iFrames, iLastCursorPos, iCurrentFrame );
|
||||
return;
|
||||
}
|
||||
|
||||
int16_t *pBuf = (int16_t *) alloca( iFrames * iChannels * sizeof(int16_t) );
|
||||
this->Mix( (int16_t *) pBuf, iFrames, iLastCursorPos, iCurrentFrame );
|
||||
std::int16_t *pBuf = (std::int16_t *) alloca( iFrames * iChannels * sizeof(std::int16_t) );
|
||||
this->Mix( (std::int16_t *) pBuf, iFrames, iLastCursorPos, iCurrentFrame );
|
||||
|
||||
/* If the device has other than 2 channels, convert. */
|
||||
if( m_pStream->m_iDeviceOutputChannels != iChannels )
|
||||
{
|
||||
int16_t *pTempBuf = (int16_t *) alloca( iFrames * m_pStream->m_iBytesPerOutputSample * m_pStream->m_iDeviceOutputChannels );
|
||||
MapChannels( (int16_t *) pBuf, pTempBuf, iChannels, m_pStream->m_iDeviceOutputChannels, iFrames );
|
||||
std::int16_t *pTempBuf = (std::int16_t *) alloca( iFrames * m_pStream->m_iBytesPerOutputSample * m_pStream->m_iDeviceOutputChannels );
|
||||
MapChannels( (std::int16_t *) pBuf, pTempBuf, iChannels, m_pStream->m_iDeviceOutputChannels, iFrames );
|
||||
pBuf = pTempBuf;
|
||||
}
|
||||
|
||||
/* If the device format isn't int16_t, convert. */
|
||||
/* If the device format isn't std::int16_t, convert. */
|
||||
if( m_pStream->m_DeviceSampleFormat != DeviceSampleFormat_Int16 )
|
||||
{
|
||||
int iSamples = iFrames * m_pStream->m_iDeviceOutputChannels;
|
||||
void *pTempBuf = alloca( iSamples * m_pStream->m_iBytesPerOutputSample );
|
||||
MapSampleFormatFromInt16( (int16_t *) pBuf, pTempBuf, iSamples, m_pStream->m_DeviceSampleFormat );
|
||||
pBuf = (int16_t *) pTempBuf;
|
||||
MapSampleFormatFromInt16( (std::int16_t *) pBuf, pTempBuf, iSamples, m_pStream->m_DeviceSampleFormat );
|
||||
pBuf = (std::int16_t *) pTempBuf;
|
||||
}
|
||||
|
||||
memcpy( pData, pBuf, iFrames * m_pStream->m_iDeviceOutputChannels * m_pStream->m_iBytesPerOutputSample );
|
||||
@@ -1139,7 +1140,7 @@ void RageSoundDriver_WDMKS::Read( void *pData, int iFrames, int iLastCursorPos,
|
||||
|
||||
bool RageSoundDriver_WDMKS::Fill( int iPacket, RString &sError )
|
||||
{
|
||||
uint64_t iCurrentFrame = GetPosition();
|
||||
std::uint64_t iCurrentFrame = GetPosition();
|
||||
// if( iCurrentFrame == m_iLastCursorPos )
|
||||
// LOG->Trace( "underrun" );
|
||||
|
||||
@@ -1233,7 +1234,7 @@ void RageSoundDriver_WDMKS::SetupDecodingThread()
|
||||
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver_WDMKS::GetPosition() const
|
||||
std::int64_t RageSoundDriver_WDMKS::GetPosition() const
|
||||
{
|
||||
KSAUDIO_POSITION pos;
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "RageSoundDriver.h"
|
||||
#include "RageThreads.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
struct WinWdmStream;
|
||||
@@ -15,7 +18,7 @@ public:
|
||||
~RageSoundDriver_WDMKS();
|
||||
RString Init();
|
||||
|
||||
int64_t GetPosition() const;
|
||||
std::int64_t GetPosition() const;
|
||||
float GetPlayLatency() const;
|
||||
int GetSampleRate() const;
|
||||
|
||||
@@ -41,7 +44,7 @@ private:
|
||||
/*
|
||||
* (c) 2002-2006 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -51,7 +54,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "PrefsManager.h"
|
||||
#include "archutils/Win32/ErrorStrings.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
REGISTER_SOUND_DRIVER_CLASS( WaveOut );
|
||||
|
||||
const int channels = 2;
|
||||
@@ -70,7 +72,7 @@ bool RageSoundDriver_WaveOut::GetData()
|
||||
return false;
|
||||
|
||||
/* Call the callback. */
|
||||
this->Mix( (int16_t *) m_aBuffers[b].lpData, chunksize_frames, m_iLastCursorPos, GetPosition() );
|
||||
this->Mix( (std::int16_t *) m_aBuffers[b].lpData, chunksize_frames, m_iLastCursorPos, GetPosition() );
|
||||
|
||||
MMRESULT ret = waveOutWrite( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
|
||||
if( ret != MMSYSERR_NOERROR )
|
||||
@@ -88,7 +90,7 @@ void RageSoundDriver_WaveOut::SetupDecodingThread()
|
||||
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
|
||||
}
|
||||
|
||||
int64_t RageSoundDriver_WaveOut::GetPosition() const
|
||||
std::int64_t RageSoundDriver_WaveOut::GetPosition() const
|
||||
{
|
||||
MMTIME tm;
|
||||
tm.wType = TIME_SAMPLES;
|
||||
@@ -136,7 +138,7 @@ RString RageSoundDriver_WaveOut::Init()
|
||||
}
|
||||
}
|
||||
deviceIds.push_back(WAVE_MAPPER); // Fallback to WAVE_MAPPER
|
||||
|
||||
|
||||
MMRESULT ret = MMSYSERR_ERROR;
|
||||
for (UINT id : deviceIds) {
|
||||
ret = waveOutOpen( &m_hWaveOut, id, &fmt, (DWORD_PTR) m_hSoundEvent, NULL, CALLBACK_EVENT );
|
||||
@@ -209,7 +211,7 @@ float RageSoundDriver_WaveOut::GetPlayLatency() const
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -219,7 +221,7 @@ float RageSoundDriver_WaveOut::GetPlayLatency() const
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "RageSoundDriver.h"
|
||||
#include "RageThreads.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
@@ -13,7 +16,7 @@ public:
|
||||
~RageSoundDriver_WaveOut();
|
||||
RString Init();
|
||||
|
||||
int64_t GetPosition() const;
|
||||
std::int64_t GetPosition() const;
|
||||
float GetPlayLatency() const;
|
||||
int GetSampleRate() const { return m_iSampleRate; }
|
||||
|
||||
@@ -37,7 +40,7 @@ private:
|
||||
/*
|
||||
* (c) 2002-2004 Glenn Maynard
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
@@ -47,7 +50,7 @@ private:
|
||||
* copyright notice(s) and this permission notice appear in all copies of
|
||||
* the Software and that both the above copyright notice(s) and this
|
||||
* permission notice appear in supporting documentation.
|
||||
*
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
|
||||
Reference in New Issue
Block a user