generated from rit-ecet-notes/new-course
166 lines
4.5 KiB
C
166 lines
4.5 KiB
C
/*
|
|
* audio_demo.c
|
|
*
|
|
* Created on: May 8, 2013
|
|
* Author: jxciee
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "io.h"
|
|
#include "system.h"
|
|
#include "alt_types.h"
|
|
#include "math.h"
|
|
#include "sys/alt_irq.h"
|
|
#include "altera_avalon_timer_regs.h"
|
|
#include "altera_avalon_timer.h"
|
|
|
|
|
|
|
|
// create standard embedded type definitions
|
|
typedef signed char sint8; // signed 8 bit values
|
|
typedef unsigned char uint8; // unsigned 8 bit values
|
|
typedef signed short sint16; // signed 16 bit values
|
|
typedef unsigned short uint16; // unsigned 16 bit values
|
|
typedef signed long sint32; // signed 32 bit values
|
|
typedef unsigned long uint32; // unsigned 32 bit values
|
|
typedef float real32; // 32 bit real values
|
|
|
|
// Global variables
|
|
#define MAX_SAMPLES 0x80000 //max sample data (16 bits each) for SDRAM
|
|
|
|
uint32 ECHO_CNT = 0; // index into buffer
|
|
uint32 SAMPLE_CNT = 0; //keep track of which sample is being read from SDRAM
|
|
uint32 CHANNELS = 0;
|
|
volatile uint16 TOGGLE = 0;
|
|
|
|
|
|
|
|
#define FIRST_TIME 1 // 1= means it is the first time running, so the file is loaded in SRAM
|
|
|
|
//set up pointers to peripherals
|
|
uint16* SdramPtr = (uint16*)NEW_SDRAM_CONTROLLER_0_BASE;
|
|
uint32* AudioPtr = (uint32*)AUDIO_0_BASE;
|
|
uint32* TimerPtr = (uint32*)TIMER_0_BASE;
|
|
uint32* PinPtr = (uint32*)PIN_BASE;
|
|
|
|
//In this ISR, most of the processing is performed. The timer interrupt is set for 20.83 us which is
|
|
// 1/48000. By setting the timer interrupt at the sampling rate, a new sample is never missed and the
|
|
// audio output fifo never gets overloaded. this is easier than using the interrupts provided with the
|
|
// audio core
|
|
void timer_isr(void *context)
|
|
{
|
|
uint16 right_sample, left_sample;
|
|
|
|
//clear timer interrupt
|
|
*TimerPtr = 0;
|
|
if (TOGGLE == 0)
|
|
{ TOGGLE = 1;}
|
|
else {TOGGLE = 0;
|
|
}
|
|
*PinPtr = TOGGLE;
|
|
|
|
|
|
if (SAMPLE_CNT < MAX_SAMPLES)
|
|
{
|
|
left_sample = SdramPtr[SAMPLE_CNT++]; //read left side sample first
|
|
|
|
if (CHANNELS == 2) //only read right sample if stereo mode
|
|
{
|
|
right_sample = SdramPtr[SAMPLE_CNT++];
|
|
AudioPtr[3] = right_sample; //in stereo, output to both sides
|
|
AudioPtr[2] = left_sample;
|
|
}
|
|
else
|
|
{
|
|
AudioPtr[3] = left_sample; //in mono, output same sample to both sides
|
|
AudioPtr[2] = left_sample;
|
|
}
|
|
}
|
|
else //this will allow continuous looping of audio. comment this out to only play once
|
|
{
|
|
SAMPLE_CNT = 0;
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//this function reads a .wav file and stores the data in the SDRAM
|
|
//first it parses the header and stores that information in variables.
|
|
//Only files with 48K sample rates and 16 bit data will work with this program.
|
|
|
|
void read_file(void)
|
|
{
|
|
//buffers for the header information
|
|
uint8 ChunkID[4], Format[4], Subchunk1ID[4], Subchunk2ID[4];
|
|
uint32 ChunkSize,Subchunk1Size, SampleRate, ByteRate, Subchunk2Size;
|
|
uint16 AudioFormat, NumChannels, BlockAlign, BitsPerSample;
|
|
uint16 Data;
|
|
FILE* fp;
|
|
uint32 i = 0;
|
|
|
|
//start reading
|
|
fp = fopen("/mnt/host/piano2.wav", "r");
|
|
|
|
if(fp == NULL)
|
|
{
|
|
printf("error, no file open!\n");
|
|
}
|
|
|
|
else
|
|
{
|
|
printf("file opened.\n");
|
|
fread(ChunkID,1,4,fp);
|
|
fread(&ChunkSize,4,1,fp);
|
|
fread(Format,1,4,fp);
|
|
fread(Subchunk1ID,1,4,fp);
|
|
fread(&Subchunk1Size,4,1,fp);
|
|
fread(&AudioFormat,2,1,fp);
|
|
fread(&NumChannels,2,1,fp);
|
|
fread(&SampleRate,4,1,fp);
|
|
fread(&ByteRate,4,1,fp);
|
|
fread(&BlockAlign,2,1,fp);
|
|
fread(&BitsPerSample,2,1,fp);
|
|
fread(&Subchunk2ID,1,4,fp);
|
|
fread(&Subchunk2Size,4,1,fp);
|
|
|
|
CHANNELS = NumChannels;
|
|
|
|
while (i < MAX_SAMPLES)
|
|
{
|
|
|
|
fread(&Data, 2, 1, fp); //read the file in one short int at a time
|
|
SdramPtr[i++] = Data; //store in sdram.
|
|
|
|
}
|
|
printf("file read \n"); //let user know file was read
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(void)
|
|
{
|
|
printf("ESD-I Audio Demo Program Running.\n");
|
|
|
|
#if (FIRST_TIME)
|
|
read_file();
|
|
#endif
|
|
|
|
//Register interrupts
|
|
//Use legacy register because the audio core forces the system to legacy
|
|
//alt_irq_register(TIMER_0_IRQ,0,timer_isr);
|
|
alt_ic_isr_register(TIMER_0_IRQ_INTERRUPT_CONTROLLER_ID,TIMER_0_IRQ,timer_isr,0,0);
|
|
//initialize timer interrupt 48Khz
|
|
TimerPtr[4] = 3;
|
|
|
|
|
|
while (1)
|
|
{
|
|
}
|
|
return 0;
|
|
}
|