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

📄 modplay.c

📁 基于lpc2148(arm7)的wav音乐格式播放器的设计
💻 C
字号:
// -*- tab-width: 4 -*-
// MOD 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 "malloc.h"

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

#include "modplay/modplay.h"
#include "modplay/mixer.h"
#include "modplay/music.h"

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


#define AmigaInt16(VAL) (((VAL & 0xFF) << 8) | ((VAL & 0xFF00) >> 8))
SampleType sample[31];

unsigned int fileSDPhysicalAddress;

unsigned int iPatternPtr = 0;
unsigned char* Pattern = NULL;

unsigned int iNumPatterns = 0;
unsigned int iNumOrders = 0;
eint16 iNumChannels = 4;
euint8* iOrderTable = NULL;	

void playMOD(char* fileName)
{
	ModType* mod = NULL;
	unsigned int iSamplePtr = 0;
	
	bExit = 0;

	StreamData[0].Data = malloc(512);
	StreamData[1].Data = (eint8*)efs.myIOman.cache_mem; //malloc(512);

	mod = malloc(sizeof(ModType) + 1);
	
/*	char* p = (char*)mod;
	for(int i = 0; i < sizeof(ModType) + 1; ++i)
	{
		p[i] = 0;
	}
*/
	if ( file_ropen(&fp, &efs.myFs, fileName) == 0 ) 
	{
		fileSDPhysicalAddress = file_getAddress(&fp, 0) * 512;
		euint32 e;
		e = file_read( &fp, sizeof(ModType), (unsigned char*)mod );
		iPatternPtr = fp.FilePtr;
		
		mod->sName[19] = 0;
		mod->sType[4] = 0;
		rprintf("[%s]\n", mod->sName);
  
		// Calculate the number of patterns based on the highest pattern number
		// listed in the order table.
		iNumPatterns = 0;
		iNumOrders = mod->iNumOrders;
		for(int i = 0; i < iNumOrders; ++i)
        {
			int j = (unsigned int) mod->iOrder[i];
			StreamData[0].Data[i] = mod->iOrder[i];
//			rprintf("Order: %u[%u]\n", i, j);
			
			if(j >= iNumPatterns)
			{
				iNumPatterns = j + 1;
			}
        }
		rprintf("Type: [%s] Orders: %u Patterns: %u\n", mod->sType, mod->iNumOrders, iNumPatterns);
		iSamplePtr = iPatternPtr + (1024 * iNumPatterns);

//		rprintf("PatternPtr: %X SamplePtr: %X\n", iPatternPtr, iSamplePtr);

		bExit = 0;
		for(int i = 0; i < 31; ++i)
		{
			ModSampleType* s = &(mod->Sample[i]);
			s->sName[21] = 0;

//			rprintf("%X: ptr: %X Len: %X LoopStart: %X LoopEnd: %X Name: %s \n", i, iSamplePtr, s->iLength, s->iLoopStart, s->iLoopLength, s->sName);
			sample[i].iFinetune = s->iFinetune;
			sample[i].iVolume = s->iVolume;
			sample[i].iLength = 2 * AmigaInt16(s->iLength);
			sample[i].iLoopStart = 2 * AmigaInt16(s->iLoopStart);
			sample[i].iLoopEnd = 2 * AmigaInt16(s->iLoopLength);
			if(sample[i].iLoopEnd > 2)
			{
				sample[i].iLoopEnd += sample[i].iLoopStart;
			}
			else
			{
				sample[i].iLoopStart = 0;
				sample[i].iLoopEnd = 0;
			}

//			rprintf("%u: %s\n", i+1, s->sName);
//			rprintf("%u: %s Finetune: %u Vol: %u Len: %X LoopStart: %X LoopEnd: %X\n", 
//					i+1, s->sName, s->iFinetune, s->iVolume, sample[i].iLength, sample[i].iLoopStart, sample[i].iLoopEnd);

			sample[i].iSDLocation = fileSDPhysicalAddress + iSamplePtr;
//			rprintf("sample[%d] SDLocation: %X Length: %X samplePtr: %X\n", i, sample[i].iSDLocation, sample[i].iLength, iSamplePtr);
			iSamplePtr += sample[i].iLength;
			//rprintf("Sample: %d Length: %d LoopEnd: %d\n", i+1, sample[i].iLength, sample[i].iLoopEnd);			
		}

//		rprintf("file size: %X\n", fp.FileSize);
		
		free(mod);
		mod = NULL;

		iOrderTable = malloc(iNumOrders + 1024);
		Pattern = iOrderTable + iNumOrders;
		for(int i = 0; i < iNumOrders; ++i)
		{
			iOrderTable[i] = StreamData[0].Data[i];
		}

		audioSize = ((freeHeapSize() - 4) >> 2) << 1; //1500; //1024;
		audioBuffer = malloc(audioSize * sizeof(eint16));
		audioBufferEnd = &audioBuffer[audioSize];

		for(int i = 0; i < audioSize; ++i)
		{
			audioBuffer[i] = 0;
		}

		if(bExit == 0)
		{
			audioFrequency(44100);
//			audioFrequency(22050);
//			audioFrequency(16537);
			filterFlags |= FILTER_16BIT;
			
			initMixer();
			initMusic();

			printHeap(NULL);

			// pre-fill the audio buffer
			e = -1;
			int j;
			while(e != 0)
			{
				e = 0;
				for(int i = 0; i < 10; ++i)
				{
					j = doMix();
					if(j != 0)
					{
						e = j;
					}
				}
			}
//			rprintf("C1[%d] C2[%d] C3[%d] C4[%d]\n", Channel[0].iMixPtr, Channel[1].iMixPtr, Channel[2].iMixPtr, Channel[3].iMixPtr);

			audioStart();
			while(bExit == 0)
			{
				doMix();
				doIdle();
			}
			FIOCLR = BIT(GREENLED);
			printHeap(NULL);

			stopSD();
			audioStop();
		}

		rprintf("Closing...\n");
		file_fclose( &fp );
	}
		
	free(audioBuffer);
	//free(Pattern);
	free(iOrderTable);
	free(StreamData[1].Data);
	free(StreamData[0].Data);
}

⌨️ 快捷键说明

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