⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shoutcaststream.cpp

📁 这是一个使用 ShortCast的IP网络流式播放的symbian的软件源码.里面有ShortCast短播协议的实现以及AAC音频,MP3音频流式播放的实现.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    TAudioFrameInfo frameInfo;

    if ( iDataType.FourCC() == KMMFFourCCCodeMP3 )
    	{
		seekOffset = Mp3SeekSync(aBuf, aLength);
		seekLen = readLen - seekOffset;
		seekPtr = aBuf + seekOffset;
		length = GetMp3FrameInfo(seekPtr, seekLen, frameInfo);
		}
	else if ( iDataType.FourCC() == KMMFFourCCCodeAAC )
		{
		seekOffset = AacSeekSync(aBuf, aLength);
		seekLen = readLen - seekOffset;
		seekPtr = aBuf + seekOffset;
		length = GetAacFrameInfo(seekPtr, seekLen, frameInfo);
		}

	if ( length > 0  &&  frameInfo.iBitRate > 0 )
		{
		iSamplingRate = frameInfo.iSamplingRate;
		iBitRate = frameInfo.iBitRate;
		iChannels = frameInfo.iChannels;
		return ETrue;
		}
	else
		{
		return EFalse;
		}
    }

// -----------------------------------------------------------------------------
// CShoutcastStream::Mp3SeekSync
// -----------------------------------------------------------------------------
//
TInt CShoutcastStream::Mp3SeekSync(
	TUint8 *aBuf,
	TInt aLength )
    {
    const TUint8* buf = aBuf;
    const TInt KMaxFrames = 3;          // number of frames to check
    const TInt KNotFound = aLength;     // sync not found position
    TAudioFrameInfo frameInfo;           // frame parameters
    TInt i = 0;
    TInt syncPos = KNotFound;
    TInt maxSeek = KMaxFrames;
    const TUint8* endPtr = buf + aLength;

    // Seek a valid frame candidate byte by byte until a valid frame
    // is found or all bytes have been checked.
    while ( buf < endPtr  &&  syncPos == KNotFound )
	    {
        TInt seekCount = 0;
        const TUint8* framePtr = buf;
        TInt frameBufLen = aLength;
        syncPos = i;

		// Check the validity of this frame candidate and the nearest next
        // frames. If they are not OK, syncPos will be set to KNotFound.
        while ( framePtr < endPtr  &&  syncPos != KNotFound  && seekCount < maxSeek )
	        {
            TInt length = GetMp3FrameInfo(framePtr, frameBufLen, frameInfo);

			if ( length == 0 )
            	{
                syncPos = KNotFound;
				}
            if ( (length > 0) && (frameInfo.iBitRate < 0 ) )
            	{
                maxSeek = 1; // free formatcase
				}
            framePtr += length;
            frameBufLen -= length;
            seekCount++;

			// consider SYNC not found if we reach end of buffer before finding 3 SYNC frames
			if ((framePtr >= endPtr) && (seekCount < maxSeek))
				{
				syncPos = KNotFound;
				aBuf += (aLength - 1);      // force an exit from while loop
				}

        	}
        buf++; aLength--; i++;
    	}
    return syncPos;
    }

// -----------------------------------------------------------------------------
// CShoutcastStream::GetMp3FrameInfo
// -----------------------------------------------------------------------------
//
TInt CShoutcastStream::GetMp3FrameInfo(
	const TUint8* aBuf,
	TInt aBufLen,
	TAudioFrameInfo& aInfo )
    {
    TInt length = 0;
    TUint temp;
    TUint lTempVal;

	if ( aBufLen >= KMp3FrameHeaderSize )
	    {
		// Extract header fields to aInfo and check their bit syntax
		// (including the sync word!). If the syntax is not OK the length
		// is set to zero.

		temp = 0;
		temp = aBuf[0] << 24;
		temp |= (aBuf[1] << 16);
		temp |= (aBuf[2] << 8);
		temp |= aBuf[3];
		if ( ((temp >> 21) & 0x7FF) != 0x7FF )
			{
			return length;
			}

		lTempVal = (temp >> 19) & 0x03;
		switch ( lTempVal )
			{
			case 0:
				aInfo.iId = 2;  // MPEG2.5
				aInfo.iFrameSamples = 576;
				break;
			case 1:
				return length;
			case 2:
				aInfo.iId = 0;  // MPEG 2
				aInfo.iFrameSamples = 576;
				break;
			case 3:
				aInfo.iId = 1;  // MPEG 1
				aInfo.iFrameSamples = 1152;
				break;
			}

		lTempVal = (temp >> 17) & 0x03;
		if ( lTempVal != 1 )
			{
			return length;
			}

		lTempVal = (temp >> 12) & 0x0F;
		aInfo.iBitRate = KMp3BitRateTable[aInfo.iId][lTempVal] * 1000;

		if ( aInfo.iBitRate == 0 )
			{
			return length;
			}

		lTempVal = (temp >> 10) & 0x03;
		if ( lTempVal == 3 )
			{
			return length;
			}
		else
			{
			aInfo.iSamplingRate = KMp3SamplingFrequencyTable[aInfo.iId][lTempVal];
			}

		aInfo.iPadding = (temp >> 9) & 0x01;

		lTempVal = (temp >> 6) & 0x03;
		aInfo.iMode = lTempVal;

		if ( lTempVal == 3 )
			{
			aInfo.iChannels = 1;
			}
		else
            {
            aInfo.iChannels = 2;
            }

        aInfo.iSamplingRateOut = aInfo.iSamplingRate;
        aInfo.iChannelsOut = 2; /* always set to stereo output */

        aInfo.iFrameSamplesOut = aInfo.iFrameSamples;

		if ( aInfo.iBitRate == -1 )
			{
			// For free mode operation
			length = KMp3MaxFrameSize;
			}

		if ( aInfo.iSamplingRate > 0  &&  aInfo.iBitRate > 0 )
			{
			length = (144 * aInfo.iBitRate) / aInfo.iSamplingRate;

			if ( aInfo.iId != 1 )
				{
				length >>= 1; /*for MPEG2 and MPEG2.5 */
				}

			if ( aInfo.iPadding )
				{
				length++;
				}
			}

		aInfo.iFrameSize = length;

    	}
    return length;
    }


// -----------------------------------------------------------------------------
// CShoutcastStream::AacSeekSync
// -----------------------------------------------------------------------------
//
TInt CShoutcastStream::AacSeekSync(
	TUint8 *aBuf,
	TInt aLength )
    {
    TInt seekLen = 0;
    while ( seekLen < (aLength - 4) )
        {
        if ( IsValidAacFrame(aBuf + seekLen, aLength - seekLen) )
        	{
            return seekLen;
			}
        seekLen++;
        }
    return aLength;
    }

// -----------------------------------------------------------------------------
// CShoutcastStream::IsValidAacFrame
// -----------------------------------------------------------------------------
//
TBool CShoutcastStream::IsValidAacFrame(
	const TUint8* aPtr,
	TInt aBufLen )
    {
	if ( (aPtr[0] == 'A') && (aPtr[1] == 'D') &&
		 (aPtr[2] == 'I') && (aPtr[3] == 'F') )
		{
		return ETrue;
		}

	if ( (aPtr[0] == 0xFF) && ((aPtr[1] >> 4) == 0xF) && // Check syncword FFF
         ((aPtr[1] >> 1) & 0x3) == 0 // Check layer == 0
         )
        {
        TInt frameLen = 0;
        frameLen = (aPtr[3] & 0x3) << 11;
        frameLen |= aPtr[4] << 3;
        frameLen |= ((aPtr[5] >> 5) & 0x7);

        if ( !frameLen || frameLen > (aBufLen-4) )
           {
           return EFalse;
           }

        // Check next frame
        const TUint8* nextFramePtr = aPtr + frameLen;
	    if ( ((nextFramePtr[0] == 0xFF) && ((nextFramePtr[1] >> 4) == 0xF)) && // Check syncword FFF
             ((nextFramePtr[1] >> 1) & 0x3) == 0 // Check layer == 0
             )
            {
            return ETrue;
            }
        }
    return EFalse;
    }

// -----------------------------------------------------------------------------
// CShoutcastStream::GetAacFrameInfo
// -----------------------------------------------------------------------------
//
TInt CShoutcastStream::GetAacFrameInfo(
	const TUint8* aBuf,
	TInt aBufLen,
	TAudioFrameInfo& aInfo )
    {
    TInt length = 0;
    TUint temp;
    TUint lTempVal;
    TUint lTemp1;
	TUint lUnSupported = 0;

	if ( aBufLen >= KAacFrameHeaderSize )
	    {
        // Extract header fields to aInfo and check their bit syntax
        // (including the sync word!). If the syntax is not OK the length
        // is set to zero.

        lTemp1 = aBuf[0] << 24;
        lTemp1 |= (aBuf[1] << 16);
        lTemp1 |= (aBuf[2] << 8);
        lTemp1 |= aBuf[3];
		temp = (lTemp1 >> 20) & 0xFFF;

		if((temp & 0xFFF) == 0xFFF)
        	{
			// ADTS Frame
			temp = (lTemp1 >> 19) & 0x01;
			aInfo.iId = temp;  // 0 for MPEG 4 and 1 for MPEG 2

            // Sampling Frequency Index
			temp = (lTemp1 >> 10) & 0x0F;

			if(temp > 11)
				{
				lUnSupported = 1;
				}
			else
				{
				aInfo.iSamplingRate = KAacSamplingFrequencyTable[temp];
				}

			// The header doesn't tell us about bitrate so use the bitrate from the server
			aInfo.iBitRate = iBitRate;

            // Channel Configuration
			lTempVal = (lTemp1 >> 6) & 0x07;

			if(lTempVal > 2)
				{
				lUnSupported = 1;
				aInfo.iChannels = lTempVal;
				}
			else if (lTempVal == 0 )
				{
				aInfo.iChannels = 2;
				}
			else
				{
				aInfo.iChannels = lTempVal;
				}

			// frame_length
			length = (lTemp1 & 0x03) << 11;

            lTemp1 = 0;
            lTemp1 = aBuf[4] << 24;
            lTemp1 |= (aBuf[5] << 16);
            lTemp1 |= (aBuf[6] << 8);

			/* adts_buffer_fullness */
			temp = temp | ((lTemp1 >> 21) & 0x7FF);

			/*Number of raw data blocks*/
			TInt numberOfRawDataBlks = ((lTemp1 >> 8) &0x03) + 1;

            if(temp > (1536 * numberOfRawDataBlks))
            	{
				/* 1536 bytes per raw datablock in the ADTS frame */
				lUnSupported = 1;
            	}

			/* Update Framesize only if the bit stream is supported */
			if(!lUnSupported)
				{
				aInfo.iFrameSize = temp;
				length = temp;
				}
        	}
    	}
    return length;
    }

// -----------------------------------------------------------------------------
// CShoutcastStream::GetIPFromURL
// Get the IP address from the URL
// -----------------------------------------------------------------------------
//
void CShoutcastStream::GetIPFromURL()
 	{
	//parse the iURL and get the IP:port
	//the URL is iURL. The target IP:port is *addr
	//we must keep the iURL constant
	TUint32 ip=0;
	TUint port=80;//the default port

	TInt length,start,end,i;
	TBuf8<URL_SIZE> url;


	//assume the http:// in front of the string
	ASSERT(iURL.Find(_L8("http://"))==0);
	start=7;
	//get the length of the url
	length=iURL.Length();

	//get the url without the http://
	url=iURL.Right(length-start);

	length = url.Find(_L8(":"));
	// get the ip addr from the url
	if ( length == KErrNotFound )
		{
		iIp = url;
		}
	else
		{
		iIp = url.Left(length);
		}

	if ( url[0] >= 48 && url[0] <=57)
		{
		//the IP starts with a number, so we have a numeric IP
		for( i = 3; i>=0; i-- )
			{
			ip = ip*256+(unsigned)atoi((const char *)url.PtrZ());
			LOG1("GetIPFromURL: ip: %u",(unsigned)atoi((const char *)url.PtrZ()));
			//get the next dot/:
			if ( i )
				{
				end=url.Locate('.');
				url.Delete(0,end+1);
				}
			}
		}
	else
		{
		//the IP does not start with a number!
		ASSERT(0);//### not handled yet
		};
	//get the port, if any
	end=url.Locate(':');
	if ( end != KErrNotFound )
		{
		//we found a port!
		url.Delete(0,end+1);
		port = (unsigned)atoi((const char *)url.PtrZ());
		}

	//get the iPath, this is what remains
	end = url.Locate('/');
	if ( end != KErrNotFound )
		{
		//we have a path
		url.Delete(0,end);//we do not delete the /
		iPath.Copy(url);
		}
	else
		{
		//there is no path! we make it /
		iPath.Copy(_L8("/"));
		}

	iAddr = new TInetAddr(ip,port);

	}

// -----------------------------------------------------------------------------
// CShoutcastStream::Disconnect
// Send disconnect event to client.
// -----------------------------------------------------------------------------
//
void CShoutcastStream::Disconnect(
	TInt aError)
	{
	LOG1("In Disconnect (status: %d)", aError);
	iDispatcher->SendEvent(TUid::Uid(KShoutcastStreamUid),KShoutcastEvent_Disconnected);
	}


// -----------------------------------------------------------------------------
// CShoutcastStream::SetVolume
// Sets the volume level
// -----------------------------------------------------------------------------
//
void CShoutcastStream::SetVolume(
	TInt aVolume )
	{
	iVolume = aVolume;
	if ( iStreamOutput )
		{
		iStreamOutput->SetVolume(aVolume);
		}
	}

// -----------------------------------------------------------------------------
// CShoutcastStream::Volume
// Get the volume level
// -----------------------------------------------------------------------------
//
TInt CShoutcastStream::Volume()
	{
	if ( iStreamOutput )
		{
		return iStreamOutput->Volume();
		}
	else
		{
		return iVolume;
		}
	}

// -----------------------------------------------------------------------------
// CShoutcastStream::MaxVolume
// Get the maximum volume level
// -----------------------------------------------------------------------------
//
TInt CShoutcastStream::MaxVolume()
	{
	if ( iStreamOutput )
		{
		return iStreamOutput->MaxVolume();
		}
	else
		{
		return 10;
		}
	}

// End of File

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -