#include "../../include/mita.h" /**< @brief MITA SDK Header */
#ifdef _DEBUG
#pragma comment(lib, "../../library/mitaD.lib")
#else
#pragma comment(lib, "../../library/mita.lib")
#endif
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#pragma warning(push)
#pragma warning(disable:4996)
MITA_STATIC
MITA_INLINE
MITA_VOID
MITA_CheckError(MITA_VOID)
{
MITA_ERROR lastError = MITA_GetLastError();
if (lastError != MITA_ERROR_OK)
{
printf("ERROR: MITA Framework error with %u codes\n", lastError);
exit(lastError);
}
}
MITA_STATIC
MITA_INLINE
MITA_BYTE
MITA_EnterKey(MITA_VOID)
{
MITA_INT32 key = 0xFF;
do
{
if (kbhit())
{
key = getch();
break;
}
} while (1);
if (key >= 'a' && key <= 'z')
key -= 32;
return key;
}
//
//ChannelMask must has channel number in high 8 bits.
// | 00000000 | MMMMMMMM MMMMMMMM MMMMMMMM |
// Nums ChannelMask
//How to set number?
// MITA_CHNFMT_SetNum(Mask, 2)
//Also you can use MITA_GuessChannelMode.
//
// The channel number must equal with channel mask.
// ChannelMask = MITA_CP_FRONT_LEFT|MITA_CP_FRONT_RIGHT; //Use two speaker
// MITA_CHNFMT_SetNum(ChannelMask, 2); //Set 2
//
MITA_STATIC
MITA_INLINE
MITA_HOUTPUT
MITA_CreateDefaultOutput(MITA_HINSTANCE hInstance, MITA_DWORD ChannelMask)
{
MITA_HOUTPUT hOutput;
MITA_HDEVICE hDevice;
MITA_DEVICEPARAM Param;
MITA_SIZE i, n;
MITA_DEVICEINFO DevInfo;
MITA_BYTE Key = 'A';
MITA_DWORD Ids[10];
MITA_BYTE MaxIds = 0;
MITA_Ins_CreateObject(hInstance, &IID_DevWinMME, &hDevice);
MITA_CheckError();
MITA_Device_GetDeviceNums(hDevice, &n);
MITA_CheckError();
printf("\nSelect a output device: \n");
_try_again:
Key = 'A';
for (i = 0; i < n; i++)
{
MITA_Device_GetDevice(hDevice, i, &DevInfo);
MITA_CheckError();
if (DevInfo.Type == MITA_CT_OUTPUT)
{
Ids[Key - 'A'] = DevInfo.DevId;
printf("[%c] Device %s [%f - %f]\n", Key, MITA_Text_ToSystemS(DevInfo.DevName, MITA_TCT_DEFAULT), DevInfo.Latency[0], DevInfo.Latency[1]);
Key++;
MaxIds++;
}
}
Key = MITA_EnterKey() - 'A';
if (Key >= MaxIds)
{
printf("ERROR: Invalid input keys, please try again.\n");
goto _try_again;
}
Param.Callback = MITA_NULL;
Param.CallbackHandle = MITA_NULL;
Param.Customer = MITA_NULL; /**< @brief for future use */
Param.ChannelFmt.mask = ChannelMask; /**< @brief The mask of channels. */
Param.ChannelFmt.sfmt = MITA_SDT_F32; /**< @brief Float32 Sample */
Param.ChannelFmt.sps = 44100.0f; /**< @brief 44.1KHz */
Param.Latency = 0.1f; /**< @brief 100 ms latency */
Param.Type = MITA_CT_OUTPUT; /**< @brief For output. */
Param.DevId = Ids[Key]; /**< @brief The id of device */
MITA_Output_CreateByDevice(hInstance, hDevice, &Param, MITA_FALSE, &hOutput);
MITA_CheckError();
return hOutput;
}
MITA_STATIC
MITA_INLINE
MITA_VOID
MITA_PrintDecSupportExts(MITA_HINSTANCE hInstance)
{
MITA_HFACTORY DecFactory;
MITA_HOBJECTLIST DecList;
MITA_SIZE i, n, j, jn;
MITA_AFD afd;
MITA_HDECODER hDecoder;
MITA_Ins_GetFactory(hInstance, MITA_MT_DECODER, &DecFactory);
MITA_CheckError();
MITA_ObjectList_Build(hInstance, DecFactory, MITA_FALSE, &DecList);
MITA_CheckError();
MITA_ObjectList_Count(DecList, &n);
for (i = 0; i < n; i++)
{
MITA_ObjectList_Get(DecList, i, &hDecoder);
MITA_Decoder_GetFileDescribeNums(hDecoder, &jn);
for (j = 0; j < jn; j++)
{
MITA_Decoder_GetFileDescribe(hDecoder, j, &afd);
printf("%s;", MITA_Text_ToSystemS(afd.ext, MITA_TCT_DEFAULT));
}
}
printf("\n");
MITA_CloseHandle(DecList);
}
void main(void)
{
MITA_HINSTANCE gInstance = MITA_NULL;
MITA_CHAR szVersion[64];
MITA_SIZE PluginCount = 0;
MITA_HINPUT hItem[3];
MITA_HOUTPUT hOutput;
MITA_HENGINE hEngine;
MITA_DWORD ChannelMask;
MITA_BYTE Key = 0;
MITA_HINPUTGROUP hGroup;
MITA_BYTE Loop = 100;
MITA_TIME CurTime;
MITA_TIME DurTime;
MITA_DWORD cur_ms, dur_ms;
MITA_CHANNELFORMAT ChannelFmt;
MITA_STATUS Status;
printf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
printf(";;Copyright(C) 杭州蜜柑科技有限公司 2008 - 2011. 保留所有权利。;;\n");
printf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
printf(";;PlayGroup Example ;;\n");
printf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
//
//1. Create a global instance handle.
gInstance = MITA_Initialize(MITA_NULL);
MITA_CheckError();
//
//2. Check SDK version, this was not necessary.
MITA_GetVersionStringA(szVersion, 64);
MITA_CheckError();
printf(";;MITA: Version %s\n", szVersion);
//
//3. Load all existed plugins.
MITA_Ins_LoadPluginFromDir(gInstance, L"../../plugins", &PluginCount);
MITA_CheckError();
printf(";;MITA: Load %u plugins\n", PluginCount);
printf(";;Support: ;;\n");
MITA_PrintDecSupportExts(gInstance);
printf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
//
//4. Create Engine Object
MITA_Engine_Create(gInstance, MITA_ENGINEFLAG_CHECKPREPARE|MITA_ENGINEFLAG_CHECKRENDER, &hEngine);
MITA_CheckError();
//
//5. Create Output Source
MITA_GuessChannelMode(8, &ChannelMask);
hOutput = MITA_CreateDefaultOutput(gInstance, ChannelMask);
//
//6. Add source to engine.
MITA_Engine_AddSource(hEngine, hOutput);
MITA_CheckError();
MITA_Output_Startup(hOutput);
MITA_CheckError();
//
//7. Load input source
MITA_Input_LoadByCacheStream(gInstance, L"../media/stereo.ogg", &hItem[0]);
MITA_CheckError();
MITA_Input_SetResampler(hItem[0], MITA_RSR_CUBIC);
MITA_Input_LoadByCacheStream(gInstance, L"../media/1.ogg", &hItem[1]);
MITA_CheckError();
MITA_Input_SetResampler(hItem[1], MITA_RSR_CUBIC);
MITA_Input_LoadByPath(gInstance, L"../media/1.mraw", &hItem[2]);
MITA_CheckError();
MITA_Input_SetResampler(hItem[2], MITA_RSR_CUBIC);
MITA_InputGroup_Create(gInstance, MITA_FALSE, &hGroup);
MITA_Engine_AddSource(hEngine, hGroup);
MITA_InputGroup_AddSource(hGroup, hItem[0]);
MITA_InputGroup_AddSource(hGroup, hItem[1]);
MITA_InputGroup_AddSource(hGroup, hItem[2]);
MITA_InputGroup_Play(hGroup, &Loop);
printf("\nGroup[A] [stereo.ogg, 1.ogg]\n");
printf("Group[B] [stereo.ogg, 1.mraw]\n");
printf("Group[C] [stereo.ogg, 1.mraw, 1.ogg]\n");
printf("Press Esc to exit\n");
do
{
if (kbhit())
{
Key = getch();
switch (Key)
{
case 'a':
case 'A':
{
MITA_Input_Stop(hItem[0], MITA_TRUE);
MITA_Input_Stop(hItem[1], MITA_TRUE);
MITA_Input_Stop(hItem[2], MITA_TRUE);
MITA_Input_Play(hItem[0], &Loop);
MITA_Input_Play(hItem[1], &Loop);
}break;
case 'b':
case 'B':
{
MITA_Input_Stop(hItem[0], MITA_TRUE);
MITA_Input_Stop(hItem[1], MITA_TRUE);
MITA_Input_Stop(hItem[2], MITA_TRUE);
MITA_Input_Play(hItem[0], &Loop);
MITA_Input_Play(hItem[2], &Loop);
}break;
case 'c':
case 'C':
{
MITA_Input_Stop(hItem[0], MITA_TRUE);
MITA_Input_Stop(hItem[1], MITA_TRUE);
MITA_Input_Stop(hItem[2], MITA_TRUE);
MITA_Input_Play(hItem[0], &Loop);
MITA_Input_Play(hItem[1], &Loop);
MITA_Input_Play(hItem[2], &Loop);
}break;
}
}
MITA_Source_GetStatus(hGroup, &Status);
MITA_Source_GetCurTime(hGroup, &CurTime);
MITA_InputGroup_GetDuration(hGroup, &DurTime);
MITA_InputGroup_GetChannelFormat(hGroup, &ChannelFmt);
MITA_Time_Cvt(&ChannelFmt, &CurTime, MITA_TIMEUNIT_MICRSECOND, &CurTime);
MITA_Time_Cvt(&ChannelFmt, &DurTime, MITA_TIMEUNIT_MICRSECOND, &DurTime);
cur_ms = (MITA_DWORD)MITA_Time_GetData(CurTime);
dur_ms = (MITA_DWORD)MITA_Time_GetData(DurTime);
printf("%10s %02u:%02u:%02u/%02u:%02u:%02u [%u channels]\r", Status==MITA_STATUS_RUNNING?"playing":(Status==MITA_STATUS_PAUSE?"pause":"stop"),
cur_ms / 1000 / 60,
cur_ms / 1000 % 60,
cur_ms / 10 % 100,
dur_ms / 1000 / 60,
dur_ms / 1000 % 60,
dur_ms / 10 % 100,
MITA_CHNFMT_GetNum(ChannelFmt.mask));
Sleep(10);
} while (Key != 27);
MITA_Engine_RemoveSource(hEngine, hOutput);
MITA_CloseHandle(hOutput);
MITA_CloseHandle(hEngine); //Release Engine Object
MITA_CloseHandle(gInstance); //Release global instance handle.
}
#pragma warning(pop)