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

📄 rawplay.c

📁 基于lpc2148(arm7)的wav音乐格式播放器的设计
💻 C
字号:
// -*- tab-width: 4 -*-
// TRAXMOD Digital Audio Player
//
// Copyright (c) 2006-2008, K9spud LLC.
// http://www.k9spud.com/traxmod/
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include "main.h"
#include "audio.h"
#include "malloc.h"
#include "mmc.h"

#include "interfaces/sd.h"
#include "interfaces/lpc2000_dbg_printf.h"
#define rprintf lpc2000_debug_printf

#include "rawplay/rawplay.h"

euint16* readBuffer;

euint16* (*PostProcessor)(euint16*) = NULL;
euint32 sd_read(hwInterface* hw, euint32 iAddress, euint32 iLen, euint8* buf);
euint32 sd_begin_read(hwInterface* hw, euint32 iAddress, euint32 iLen, euint8* buf);

euint32 sd_read(hwInterface* hw, euint32 iAddress, euint32 iLen, euint8* buf)
{
	euint32 iRead = 0;

	while(iRead < iLen)
	{
		SD_ReadBlock(iAddress, buf, 512);
		iAddress++;
		buf 	 += 512;
		iRead    += 512;
	}
	
	return iRead;
}

euint32 sd_begin_read(hwInterface* hw, euint32 iAddress, euint32 iLen, euint8* buf)
{
	SD_BeginRead(iAddress*512, buf, 512);	
	return iLen;
}


// Plays a RAW audio file using the FAT filesystem to initially
// find the first sector address of the file, then reads from
// the SD Card directly (no filesystem layer). Will play garbage
// on fragmented files.
void playRAW(char* fileName)
{
	bExit = 0;
	
	readBuffer = malloc(iSD_BlockLength);

	audioSize = 1024;
	audioBuffer = malloc(audioSize * sizeof(euint16));
	audioBufferEnd = &audioBuffer[audioSize];
	
	if ( file_ropen(&fp, &efs.myFs, fileName) == 0 ) 
	{
		euint32 iAddress, iEndAddress;
		unsigned short e, i;
		eint16* p;
		hwInterface* hw = fp.fs->part->disc->ioman->iface;
		
		iAddress = file_getAddress(&fp, 0);
//		iAddress = (iAddress / 512) * 512;
		iEndAddress = iAddress + (fp.FileSize / 512);
		rprintf("LBA: %d Size: %d\n", iAddress, fp.FileSize);
		
		//e = file_read( &fp, audioSize * sizeof(euint16), (euint8*)audioBuffer );
		p = audioBuffer;
		for(i = 0; i < 2; i++)
		{
			e = sd_read(hw, iAddress, iSD_BlockLength, (euint8*)readBuffer);
			iAddress++;
			if(readBuffer[0] > 0x6000 && readBuffer[0] < 0xA000)
			{
				PostProcessor = &Unsigned16Bit;
			}
			else
			{
				PostProcessor = &Signed16Bit;			
			}
			p = (eint16*)PostProcessor((euint16*)p);
		}

		audioFrequency(44100);
		filterFlags &= ~FILTER_16BIT;
		//filterFlags |= FILTER_16BIT;

		audioStart();
		printHeap("[rawplay]");
		i = 0;

		euint8 iNeedPostProcess = 0;
		while ( iAddress < iEndAddress && bExit == 0) 
		{
//			while(iPlayPtr < (audioSize >> 1))
			while(playPointer < &audioBuffer[audioSize >> 1])
			{
				if(iNeedPostProcess)
				{
					if(BytesLeftToRead == 0)
					{
//					rprintf("SSPIMSC: %d VICIntEnable: %X SSPSR: %X\n", SSPIMSC, VICIntEnable, SSPSR);
						PostProcessor((euint16*)p);
						SD_StopTransmission();
						iNeedPostProcess = 0;
					}
				}

				doIdle();
			}

			p = audioBuffer;

			e = sd_begin_read(hw, iAddress, iSD_BlockLength, (euint8*)readBuffer);
			iAddress++;
			iNeedPostProcess = 1;
			
//			while(iPlayPtr >= (audioSize >> 1))
			while(playPointer >= &audioBuffer[audioSize >> 1])
			{
//				rprintf("Feed: %d Read: %d\n", iSD_FeedBytes, iSD_ReadBytes);
				if(iNeedPostProcess)
				{
					if(BytesLeftToRead == 0)
					{
//					rprintf("SSPIMSC: %d VICIntEnable: %X SSPSR: %X\n", SSPIMSC, VICIntEnable, SSPSR);
						p = (eint16*)PostProcessor((euint16*)p);
						SD_StopTransmission();
						iNeedPostProcess = 0;
					}
				}

				doIdle();				
			}


			e = sd_begin_read(hw, iAddress, iSD_BlockLength, (euint8*)readBuffer);
			iAddress++;
			iNeedPostProcess = 1;				
			
			i++;
			unsigned int iBatt = readBatt();
			if(iBatt < 0xA000 && ledRead(GREENLED))
			{
				if(ledRead(REDLED))
				{
					if(i > 70)
					{
						i = 0;
						ledToggle(REDLED);
					}
				}
				else
				{
					if(i > 10)
					{
						i = 0;
						ledToggle(REDLED);
					}				
				}
			}
			else
			{
				if(ledRead(REDLED) == 0)
				{
					ledToggle(REDLED);
				}
				
				if(ledRead(GREENLED))
				{
					if(i > 200)
					{
						i = 0;
						ledToggle(GREENLED);
					}
				}
				else
				{
					if(i > 15)
					{
						i = 0;
						ledToggle(GREENLED);
					}
				}				
			}
		}

		// make sure to stop interrupt driven card read before accessing
		// card using other functions.
		while(BytesLeftToRead);
		SD_StopTransmission();
		
		file_fclose( &fp );
		audioStop();
	}
	
	free(audioBuffer);
	free(readBuffer);
}

euint16* Unsigned16Bit(euint16* buf)
{
	unsigned int i = 0, iReadPtr = 0;
	unsigned int iSample;
	
	while(iReadPtr < (iSD_BlockLength >> 1))
	{
		iSample = readBuffer[iReadPtr++] - 0x8000;
		buf[i++] = iSample;
		buf[i++] = 0;
	}
	return &(buf[i]);
}

euint16* Signed16Bit(euint16* buf)
{
	unsigned int i = 0, iReadPtr = 0;
	unsigned int iSample;
	
	while(iReadPtr < (iSD_BlockLength >> 1))
	{
		iSample = readBuffer[iReadPtr++];
		buf[i++] = iSample;
		buf[i++] = 0;
	}
	return &(buf[i]);
}


/*

euint16* PostProcess16(euint16* buf)
{
	unsigned int i = 0, iReadPtr = 0;
	unsigned int iSample, iMSB, iLSB;
	
	while(iReadPtr < (READ_BUFFER_SIZE >> 1))
	{
		iSample = readBuffer[iReadPtr++] + CALIBDACo;
		iMSB = ((iSample * CALIBDACa) >> 16);
		iLSB = (iSample - (iMSB * CALIBDACb));
		while(iLSB > (PWMPERIOD - LSBOFFSET))
		{
			iLSB -= CALIBDACb;
			iMSB++;			
		}
		buf[i++] = (PWMPERIOD - MSBOFFSET) - iMSB; // MSB

		if(iPlayLSB)
		{		
			if(iLSB > PWMPERIOD || iLSB < 0)
			{
				if(i & 2)
				{
					iRGTDAC = iSample;
				}
				else
				{
					iLFTDAC = iSample;
				}
			}
			
			buf[i++] = (PWMPERIOD - LSBOFFSET) - iLSB; // LSB
		}
		else
		{
			buf[i++] = PWMPERIOD + 1; // disable LSB output.
		}
	}
	return &(buf[i]);
}
*/

/*
// Plays a RAW audio file from a FAT file system. 
void playRAWfat(char* fileName)
{
	bExit = 0;
	
	audioSize = 2048;
	audioBuffer = malloc(audioSize * sizeof(euint16));
	if(audioBuffer == NULL)
	{
		rprintf("Can't allocate play buffer.\n");
		return;
	}
	
	if ( file_fopen( &fp, &efs.myFs, fileName , 'r' ) == 0 ) 
	{
		euint32 iAddress;
		unsigned short e, i;
		euint16* p;

		iAddress = file_getAddress(&fp, 0);
		
		e = file_read( &fp, audioSize * sizeof(euint16), (euint8*)audioBuffer );
		PostProcess16(audioBuffer, audioSize, e >> 1);

		audioFrequency(44100);
		audioStart();
		i = 0;
		while ( e != 0 && bExit == 0) 
		{
			while(iPlayPtr < (audioSize >> 1))
			{
				doIdle();
			}
			e = file_read( &fp, audioSize, (euint8*)audioBuffer );
			PostProcess16(audioBuffer, audioSize>>1, e >> 1);

			while(iPlayPtr >= (audioSize >> 1))
			{
				doIdle();
			}

			p = &(audioBuffer[audioSize>>1]);
			e = file_read( &fp, audioSize, (euint8*)p );
			PostProcess16(p, audioSize>>1, e >> 1);
			
			i++;
			if(i > 100)
			{
				i = 0;
				ledToggle();
			}
		}
		file_fclose( &fp );
		audioStop();
	}
	
	free(audioBuffer);
}
*/

void ledToggle(unsigned int iLEDPIN)
{
	static unsigned char state=0;
	
	state = !state;
	if (state) FIOCLR = BIT(iLEDPIN);	// set Bit = LED on
	else FIOSET = BIT(iLEDPIN);	// set Bit = LED off (active low)
}

int ledRead(unsigned int iLEDPIN)
{
	return (FIOPIN & (1 << iLEDPIN));
}

⌨️ 快捷键说明

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