2009年10月13日

Direct2D

久しくDirectX関連はウォッチしていなかったのだけれど、Windows 7からDirect2Dという2DグラフィックスAPIが搭載されるとのこと。
これはGDI,GDI+に取って代わるもので、D3Dの上で構築されている。
当初DirectXは2Dのゲーム用ビットマップグラフィックスAPIで、それから3D APIが搭載され、2D部分が(名目上)なくなって、ビジネスグラフィックスの置き換えのためにまた復活した。
GDI+と違い、ハードウェアアクセラレーションが効くとのことで普及するのではないかと見られている。
しかし、本当はビデオメモリに余計なオーバーヘッドなく読み書きができるようになれば後はソフトウェアでなんとかなりそうななんだが、そういう風には世の中は流れてはいかないようだ。

posted by S.F. at 20:00| 千葉 晴れ| Comment(0) | Library | このブログの読者になる | 更新情報をチェックする

2009年10月11日

WASAPI(17) - JUCEのWASAPIサポート

JUCEのWASAPIサポートはすでに始まっていて、ソースコードも見ることができる。
http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=4404
ただ、いまのところ共有モードのみで、排他モードのサポートはないようだ。おそらくWindows 7が共有モードで低レイテンシ再生・録音が可能になっているためであろうと考える。
http://msdn.microsoft.com/en-us/library/dd756612(VS.85).aspx
とりあえず私は、上記ソースコードも参考にしながら、排他モードでのサポートを目指すことにする。

posted by S.F. at 16:39| 千葉 晴れ| Comment(0) | WASAPI | このブログの読者になる | 更新情報をチェックする

WASAPI(16) - Boost.Assignment

ptr_vectorの初期化にBoost.Assignemntを使ってみようとして午前中四苦八苦していた。
こうしたかったのだ。
boost::ptr_vector<WAVEFORMATEX> WASAPI::impl::wave_formats_ = 
		ptr_list_of<WAVEFORMATEX<
		( WAVE_FORMAT_PCM, 2, 192000,768000, 4, 16, 0 )    
		( WAVE_FORMAT_PCM, 2, 96000, 384000, 4, 16, 0 )    // 96-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 48000, 192000, 4, 16, 0 )    // 48-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0 )    // 44.1-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 32000, 128000, 4, 16, 0 )    // 32-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2,  8000,  32000, 4, 16, 0 )    // 8-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 48000,  96000, 2,  8, 0 )    // 48-kHz, 8-bit stereo
		( WAVE_FORMAT_PCM, 2, 44100,  88200, 2,  8, 0 )    // 44.1-kHz, 8-bit stereo
		( WAVE_FORMAT_PCM, 2, 32000,  64000, 2,  8, 0 )    // 32-kHz, 8-bit stereo
		( WAVE_FORMAT_PCM, 2,  8000,  16000, 2,  8, 0 );//    // 8-kHz, 8-bit stereo

四苦八苦した結果、下記のとおりにすればできることがわかった。
(1)WAVEFORMATEXを継承した構造体、sf:WAVEFORMATEXを作成してコンストラクタを実装する。
(2)#define BOOST_ASSIGN_MAX_PARAMS 7をptr_list_of.hppをインクルードする前に入れる。
#define BOOST_ASSIGN_MAX_PARAMS 7
#include <boost/assign.hpp>
#include <oost/assign/ptr_list_of.hpp>
namespace sf {

struct WAVEFORMATEX : public ::WAVEFORMATEX {
	WAVEFORMATEX(
		WORD        FormatTag = 0,         /* format type */
		WORD        Channels = 0,          /* number of channels (i.e. mono, stereo...) */
		DWORD       SamplesPerSec = 0,     /* sample rate */
		DWORD       AvgBytesPerSec = 0,    /* for buffer estimation */
		WORD        BlockAlign = 0,        /* block size of data */
		WORD        BitsPerSample = 0,     /* number of bits per sample of mono data */
		WORD        Size = sizeof(::WAVEFORMATEX)            /* the count in bytes of the size of */
		)  
		{
			wFormatTag = FormatTag;
			nChannels = Channels;
			nSamplesPerSec = SamplesPerSec;
			nAvgBytesPerSec = AvgBytesPerSec;
			nBlockAlign = BlockAlign;
			wBitsPerSample = BitsPerSample;
			cbSize = Size;			
		};
};

boost::ptr_vector<sf::WAVEFORMATEX> WASAPI::impl::wave_formats_ = 
		ptr_list_of<sf::WAVEFORMATEX>
		( WAVE_FORMAT_PCM, 2, 192000,768000, 4, 16, 0 )    
		( WAVE_FORMAT_PCM, 2, 96000, 384000, 4, 16, 0 )    // 96-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 48000, 192000, 4, 16, 0 )    // 48-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0 )    // 44.1-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 32000, 128000, 4, 16, 0 )    // 32-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2,  8000,  32000, 4, 16, 0 )    // 8-kHz, 16-bit stereo
		( WAVE_FORMAT_PCM, 2, 48000,  96000, 2,  8, 0 )    // 48-kHz, 8-bit stereo
		( WAVE_FORMAT_PCM, 2, 44100,  88200, 2,  8, 0 )    // 44.1-kHz, 8-bit stereo
		( WAVE_FORMAT_PCM, 2, 32000,  64000, 2,  8, 0 )    // 32-kHz, 8-bit stereo
		( WAVE_FORMAT_PCM, 2,  8000,  16000, 2,  8, 0 );//    // 8-kHz, 8-bit stereo

posted by S.F. at 12:58| 千葉 晴れ| Comment(0) | WASAPI | このブログの読者になる | 更新情報をチェックする

2009年10月10日

CComPtr

VC Express EditionにはATLがついてないので、CComPtr(COMスマートポインタ)がない。
boost::intrusive_ptrで代用していた(ちなみに代用方法はこちら参照)のだが、どうにも面倒臭いのでググってみたらやはりCComPtrクローンを作っている人がいた。
http://www.codeproject.com/KB/COM/ccomptr.aspx
http://www.firefly-vj.net/imagery/?itemid=354
上記2つを適当にマージして作ったのが下記コード。
#ifndef _COMPTR_H_
#define _COMPTR_H_

template<class INTERFACE, const IID* piid = NULL>
class CComPtr
{
public:
	CComPtr()
	{
		interface_ = NULL;
	}

	CComPtr(INTERFACE* lPtr)
	{
		interface_ = NULL;

		if (lPtr != NULL)
		{
			interface_ = lPtr;
			interface_->AddRef();
		}
	}

	CComPtr(const CComPtr<INTERFACE, piid>& RefComPtr)
	{
		interface_ = NULL;
		interface_ = (INTERFACE*)RefComPtr;

		if (interface_)
		{
			interface_->AddRef();
		}
	}
	CComPtr(IUnknown* pIUnknown, IID iid)
	{
		interface_ = NULL;

		if (pIUnknown != NULL)
		{
			pIUnknown->QueryInterface(iid, (void**)&interface_);
		}
	}
	~CComPtr()
	{
		if (interface_)
		{
			interface_->Release();
			interface_ = NULL;
		}
	}

public:
	operator INTERFACE*() const
    {
        return interface_;
    }

	INTERFACE& operator*() const
    {
		return *interface_;
    }

	INTERFACE** operator&()
    {
        return &interface_;
    }

	INTERFACE* operator->() const
	{
		return interface_;
	}

	INTERFACE* operator=(INTERFACE* lPtr)
	{

		if (IsEqualObject(lPtr))
		{
			return interface_;
		}

		interface_->Release();
		lPtr->AddRef();
		interface_ = lPtr;
		return interface_;
	}

	INTERFACE* operator=(IUnknown* pIUnknown)
    {
		assert(pIUnknown != NULL);
		assert(piid != NULL);
        pIUnknown->QueryInterface(*piid, (void**)&interface_);
		assert(interface_ != NULL);
		return interface_;
    }

	INTERFACE* operator=(const CComPtr<INTERFACE, piid>& RefComPtr)
	{
		assert(&RefComPtr != NULL);
		interface_ = (INTERFACE*)RefComPtr;

		if (interface_)
		{
			interface_->AddRef();
		}
		return interface_;
	}

	void Attach(INTERFACE* lPtr)
    {
        if (interface_)
		{
			interface_->Release();
		}
		interface_ = lPtr;
    }

    INTERFACE* Detach()
    {
        INTERFACE* lPtr = interface_;
        interface_ = NULL;
        return lPtr;
    }

	void Release()
	{
		if (interface_)
		{
			interface_->Release();
			interface_ = NULL;
		}
	}

	bool IsEqualObject(IUnknown* pOther)
	{
		assert(pOther != NULL);
		IUnknown* pUnknown = NULL;
		interface_->QueryInterface(IID_IUnknown, (void**)&pUnknown);
        bool Result = (pOther == pUnknown) ? true : false;
		pUnknown->Release();
		return Result;
	}

    HRESULT CreateInstance(const GUID &clsid, IID iid=GUID_NULL)
	{
		if(IsEqualObject(iid, GUID_NULL)) iid=__uuidof(T);
		HRESULT hr = ::CoCreateInstance(clsid, NULL
			,CLSCTX_INPROC_SERVER
			,iid
			,(void**)(&interface_));
		return hr;
    }

private:
	INTERFACE* interface_;
};

#endif // _COMPTR_H_
しかし、今頃になってCOM Interfaceラッパを作る羽目になるとは。。。
posted by S.F. at 18:21| 千葉 雨| Comment(0) | Library | このブログの読者になる | 更新情報をチェックする

SyntaxHighlighter

SyntaxHighlighterを2.0.320にアップした。
http://alexgorbatchev.com/wiki/SyntaxHighlighter
posted by S.F. at 16:19| 千葉 雨| Comment(0) | Library | このブログの読者になる | 更新情報をチェックする

相変わらず大量...

20091010.jpg
posted by S.F. at 14:02| 千葉 曇り| 日記 | このブログの読者になる | 更新情報をチェックする

WASAPI(15) - MemoryGuared

IMMDeviceGetId( LPWSTR *ppstrId)で、デバイスIDの文字列が取得できるのだが、この文字列はOSでアロケートされたメモリに格納されるので、不要になったらCoTaskMemFree()しなくてはならない。
こういうのは忘れやすい僕にとっては危険な仕様なので、ラッパクラスを作って確実に解放するようにしたい。
すこしググってみたらやっぱり同じことを考えている人がいて、ポリシーベースの立派なものがすでに作られていたので、早速拝借することにする。
<元ネタ>https://forums.codegear.com/thread.jspa?messageID=97614&#97614


namespace sf
{
// policy class
struct HeapMemoryFreePolicy
{
template< typename T >
void operator()( const T* AMemory ) const
{
if( NULL != AMemory )
::HeapFree( ::GetProcessHeap(), 0, AMemory );
}
};
// policy class
struct LocalMemoryFreePolicy
{
template< typename T >
void operator()( const T* AMemory ) const
{
if( NULL != AMemory )
::LocalFree( AMemory );
}
};
// policy class
struct CoTaskMemoryFreePolicy
{
template< typename T >
void operator()( const T* AMemory ) const
{
if( NULL != AMemory )
::CoTaskMemFree( AMemory );
}
};
// base guard class
template< typename T,
class TFreePolicy
class BaseMemory
{
private:
T *FMemory;

public:
BaseMemory( T* AMemory = NULL )
: FMemory( AMemory ) {}

virtual ~BaseMemory( void )
{ Reset(); }

T* Release( void )
{
T *tmp = FMemory;
FMemory = NULL;
return tmp;
}

void Reset( T* AMemory = NULL )
{
if( AMemory != FMemory )
{
if( NULL != FMemory )
TFreePolicy( FMemory );

FMemory = AMemory;
}
}

T* Get( void )
{ return FMemory; }

T** operator&( void )
{ return &FMemory; }

};
template< typename T >
class HeapMemory : public BaseMemory< T, 
HeapMemoryFreePolicy >
{
public:
HeapMemory( T* AMemory = NULL )
: BaseMemory< T, HeapMemoryFreePolicy >( AMemory )
{ }
};
template< typename T >
class LocalMemory : public BaseMemory< T, 
LocalMemoryFreePolicy >
{
public:
LocalMemory( T* AMemory = NULL )
: BaseMemory< T, LocalMemoryFreePolicy >( AMemory )
{ }
};
template< typename T >
class CoTaskMemory : public BaseMemory< T, 
CoTaskMemoryFreePolicy >
{
public:
CoTaskMemory( T* AMemory = NULL )
: BaseMemory< T, CoTaskMemoryFreePolicy >( AMemory )
{ }
};

} // end namespace sf

posted by S.F. at 08:02| 千葉 | Comment(0) | WASAPI | このブログの読者になる | 更新情報をチェックする

2009年10月09日

WASAPI(14) - IUnknownImpl

小ネタ。 IUnknownを実装するクラス。
template <typename COMInterface> 
struct IUnknownImpl : public COMInterface 
{
	IUnknownImpl() : ref_(1) {}; 
	virtual ~IUnknownImpl() {};
	ULONG __stdcall AddRef()
	{
		return InterlockedIncrement(&ref_);
	}

	ULONG __stdcall Release()
	{
		ULONG ref = InterlockedDecrement(&ref_);
		if (0 == ref)
		{
			delete this;
		}
		return ref;
	}

	HRESULT __stdcall QueryInterface(REFIID riid, VOID **ppObj)
	{
		if (IID_IUnknown == riid)
		{
			AddRef();
			*ppObj = (IUnknown*)this;
		}
		else if (__uuidof(COMInterface) == riid)
		{
			AddRef();
			*ppObj = (COMInterface*)this;
		}
		else
		{
			*ppObj = NULL;
			return E_NOINTERFACE;
		}
		return S_OK;
	}
private:
	LONG ref_;
};
<使い方>
struct MMNotificationClient : public IUnknownImpl<IMMNotificationClient> 
{ ... }
posted by S.F. at 22:06| 千葉 晴れ| Comment(0) | WASAPI | このブログの読者になる | 更新情報をチェックする

2009年10月07日

WASAPI(13)

ようやくデバイスの一覧が表示可能に。
でもまだハリボテ状態。
20091007.png
posted by S.F. at 21:11| 千葉 曇り| WASAPI | このブログの読者になる | 更新情報をチェックする

2009年10月04日

WASAPI(12)

とりあえず、ドライバ設定画面に表示されるようにした。
本格的な実装はこれから。
20091004.png

・DSOUNDではドライバの列挙はコールバック関数で行っていたけれども、WASAPIでは以下のようにドライバを列挙する。

1.IMMDeviceEnumeratorをCoCreateInstanceする
2.IMMDeviceEnumerator->EnumAudioEndpointsでデバイスのコレクション(IMMDeviceCollection)を取得する。

・個々のエンドポイントデバイスを取り出すには、IMMDeviceCollection->Item(DWORD index,IMMDevice**)でデバイス(IMMDevice)を取得する

・デバイスの属性を取得するにはIMMDevice->OpenPropertyStore()でIPropertyStoreを取得する

・各属性を取り出すには、IPropertyStore ->GetValue()で取り出す。
取り出した値はPROPVARIANT型である

とまあ、COM全開でなんとも面倒くさいのである。




posted by S.F. at 17:53| 千葉 晴れ| Comment(0) | WASAPI | このブログの読者になる | 更新情報をチェックする

2009年10月03日

JUCEのWDM

JUCEライブラリのコードでWDMAudioを実装してそうな雰囲気のコードを発見。しかし、1.50ではまだ未対応のようだ。WDMのコード自体は発見できなかったので。
extern AudioIODeviceType* juce_createDefaultAudioIODeviceType();

#if JUCE_WIN32 && JUCE_ASIO
  extern AudioIODeviceType* juce_createASIOAudioIODeviceType();
#endif

#if JUCE_WIN32 && JUCE_WDM_AUDIO
  extern AudioIODeviceType* juce_createWDMAudioIODeviceType();
#endif

void AudioDeviceManager::createAudioDeviceTypes (OwnedArray <AudioIODeviceType>& list)
{
    AudioIODeviceType* const defaultDeviceType = juce_createDefaultAudioIODeviceType();

    if (defaultDeviceType != 0)
        list.add (defaultDeviceType);

#if JUCE_WIN32 && JUCE_ASIO
    list.add (juce_createASIOAudioIODeviceType());
#endif

#if JUCE_WIN32 && JUCE_WDM_AUDIO
    list.add (juce_createWDMAudioIODeviceType());
#endif
}
posted by S.F. at 21:07| 千葉 | Comment(0) | Library | このブログの読者になる | 更新情報をチェックする

YouTubeにアップしなおし

ニコ動にアップしていたものにキャプチャした画像を加え、YouTubeに再度アップした。
キャプチャツールは「BB FlashBack Express 2」を使用した。



posted by S.F. at 15:56| 千葉 雨| Comment(0) | Aodix | このブログの読者になる | 更新情報をチェックする

2009年10月01日

マスコミ

朝日の一面に、鳩山さんの「小」スキャンダルが大見出しで載っていた。
自民党が与党であったときも散々見てきたこのマスコミによる、「小スキャンダルで民意を煽動し、コロコロ大臣・総理を変えさせる」のは何の目的で行っているのか?
マスコミはその多大なる影響力をもってこの国をどうしたいのだろうか?僕には破滅に導いているとしか思えない。

なぜもっと真摯に公平に報道しないのだろう。
なぜ事の重大性と紙面の面積をあえて変えて、さも重大であることのように見せようとするのだろうか?

人間は「善・悪」を併せ持つ生き物であり、政治家であっても悪の部分が存在するはずである。そういう前提で物事を語るべきである。
マスコミは政治家に「悪」の部分はすべて排除せよといわんばかりだ。
しかも、その悪が犯罪であるのかどうかわからない段階でまるで「悪」であるかのように書き立てる。

人間は「悪」を内包するからこそ「悪」を抑制するための「法」が必要なのであり、「悪」をできる限り減らすために日々反省し、「遵法」にいそしまなければならない。
過去に法の過ちを冒すことは人間なら誰しもあることであり、「反省」および「厚生」をして現在遵法状態にある人間を、過去に遡及して現状を顧みず批判する記事も本当に多い。


マスコミがいかにいい加減かは今に始まったことではない。

マスコミは戦前のファシズムの台頭を助け、破滅へと導くよう国民を煽動したという事実がある。
戦後マスコミは自省をしただろうか?ファシズムという「悪」なるものに屈せず、沈着冷静に事実を公平に報道したかどうかという点において。
posted by S.F. at 13:59| 千葉 曇り| 日記 | このブログの読者になる | 更新情報をチェックする

2009年09月30日

疲れた、、、、。

今日は忙しさに目が回りそうな1日だった。
疲れた。。。
posted by S.F. at 19:46| 千葉 雨| 日記 | このブログの読者になる | 更新情報をチェックする

2009年09月29日

WASAPI(11)

WASAPIデバイスのテストをするために(まだぜんぜん完成していないが)PluginHostサンプルのコードをマージした。
20090929.png
posted by S.F. at 22:09| 千葉 霧| WASAPI | このブログの読者になる | 更新情報をチェックする