Hi, I'm trying to implement some sound mixing playing effect within our game. To minimize the size of our sis file, we'd decided to use mp3 as our prime audio choice. So when the user clicks to install our software, our app would at first decode the mp3 files at first.

I've tried the follow plan as most mentioned in the internet, I tried to add the signed short number from each pcm source to an int, and then divide the integer by the number of the to-be-mixed channel,
That is,
Int result = (short)pcm1 + pcm2 + .... pcmN
short value = result / N;
really can't say the effect is good enough, too much noise.


So far, Here is my code for mixing the pcm data(signed 16 bit LE) decoded from mp3, for me at least, it is the best solution, however, it's still not so perfect that there is still some noise during mixing. And I'm also confused why I tried to truncate the overflowing numbers, that is uncomment the following statements, I got a even worse result.
Code:
//		if (result < -0x8000)
//			result = -0x8000;
//		if (result > 0x7FFF)
//			result = 0x7FFF;
Code:
void CStreamPlayer::FillBufferL()
{
	TInt byteLen = 0;
	TInt maxVolume = iPlayer->MaxVolume();
	
	/* 计算要使用的buffer长度 */
	for(TInt k = 0; k < iChannelNum; k++)
	{
		psoundchannel ch = (psoundchannel)hashtable_search_by_index(channels, k);
		if(ch->length - ch->pos >= KMAXBufferSize)
		{
			byteLen = KMAXBufferSize;
			OBJECT_FREE(ch);
			break;
		}
		else
		{
			if(byteLen < (ch->length - ch->pos))
			{
				byteLen = ch->length - ch->pos;
			}
		}
		OBJECT_FREE(ch);
	}
	
	if(byteLen <= 0)
	{
		byteLen = 0;
		return;
	}
	
	if(iDataBuffer == NULL)
	{
		iDataBuffer = (BYTE*)malloc(sizeof(BYTE) * KMAXBufferSize);
		if(iDataBuffer == NULL)
			return;
	}
	
	SYNCHRONIZED_LOCK(channels);
	for(TInt i = 0; i < byteLen / 2; i++)
	{
		int result = 0;
//		short shortRes = 0;
		
		for(TInt j = 0; j < iChannelNum; j++)
		{
			short data = 0;
			psoundchannel ch = (psoundchannel)hashtable_search_by_index(channels, j);
			
			if(ch->pos + 2 <= ch->length)
			{
				BYTE b1, b2;
				b1 = (BYTE)(ch->data->value[ch->pos]);
				b2 = (BYTE)(ch->data->value[ch->pos + 1]);
				ch->pos += 2;
				data = (b1 << 8) | b2;
			}
//			else if(ch->pos + 1 == ch->length)
//			{
//				BYTE b1;
//				b1 = (BYTE)(ch->data->value[ch->pos]);
//				data = b1;
////				data = (b1 << 8);
//				ch->pos += 1;
//			}
			else
			{
				if(ch->isLoop)
				{
					ch->pos = 0;
					BYTE b1, b2;
					b1 = (BYTE) (ch->data->value[ch->pos]);
					b2 = (BYTE) (ch->data->value[ch->pos + 1]);
					ch->pos += 2;
					data = (b1 << 8) | b2;
				}
				else
				{
					continue;
				}
			}
			
			result += data;
			OBJECT_FREE(ch);
		}

//		if (result < -0x8000)
//			result = -0x8000;
//		if (result > 0x7FFF)
//			result = -0x8000;
			
		iDataBuffer[2 * i ] = (BYTE)(result >> 8);
		iDataBuffer[2 * i + 1] = (BYTE)result; 
//		print_value("C:\\sounddata.data", result);
	}
	SYNCHRONIZED_UNLOCK(channels);
	
	iWritePtr.Set((TUint8 *)iDataBuffer, byteLen);
	TRAPD(myErr, iPlayer->WriteL(iWritePtr));
	if(myErr != KErrNone)
	{
		// something else.
	}
	RecheckChannel();
}
Would any kind guy pls provide some better solution or give me some suggestions on this?

Thanks in advance!