Nios® II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
12421 Discussions

Audio Tone Generation on DE1-SOC Linux User Space

vimfulDang
Beginner
271 Views

Hello, I'm having trouble generating sinusoidal tones to the Line Out in Linux User Space on DE1-SOC board. Attached is my code, I'm sure there's some fundamental concept that I'm missing so I'd appreciate the feedback.

#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "../address_map_arm.h"
#include <signal.h>

#define SAMPLE_RATE 48000
#define TWO_PI	6.28318531
static double note[13] = {261.626, 277.183, 293.665, 311.127, 329.628, 
					349.228, 369.994, 391.995, 415.305, 440.000, 466.164,
					493.883, 523.251};
static unsigned int * audio_base_ptr;

//Function Prototype
void write_to_audio_port(double);

volatile sig_atomic_t stop;
void catchSIGINT (int signum) {
	stop = 1;
}

int main (void) {

	int fd = -1;
	int i = 0;
	stop = 0;
	void * LW_virtual;

	int nth_sample;
	double freq;
	signal(SIGINT, catchSIGINT);
	// Max volume when multiplied by sin() which ranges from -1 to 1;
	int vol = 0x7FFFFFF;

	if ((fd = open("/dev/mem", (O_RDWR | O_SYNC))) == -1) {
		printf("ERROR: could not open \"/dev/mem\"...\n");
		return (-1);
	}

	LW_virtual = mmap(NULL, LW_BRIDGE_SPAN, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 
		LW_BRIDGE_BASE);

	if (LW_virtual == NULL) {
		printf("ERROR: could not mmap()...\n");
		close(fd);
		return (-1);
	}
	
	audio_base_ptr = (unsigned int *) (LW_virtual + AUDIO_BASE);

	//Clear Write FIFO & set back to zero
	*(audio_base_ptr) |= 0x8;
	*(audio_base_ptr) &= 0xFFFFFFF7;

	//printf("left:%#x right:\n", *(audio_base_ptr + 1) & 0xFF000000, *(audio_base_ptr + 1) & 0x00FF0000);

	for (i = 0; ((i < 13) && !stop); i++) {
		freq = note[i];
		printf("Playing frequency: %f\n", freq);
		for (nth_sample = 0; nth_sample < 14400; nth_sample++) {
			write_to_audio_port(vol * sin(nth_sample * M_PI * freq / SAMPLE_RATE));
			//printf("%d: %d\n", nth_sample, (int) (vol * sin(nth_sample * M_PI * freq / SAMPLE_RATE)));
		}
	}

	//Unmap
	printf("Unmapping\n");
	if (munmap(LW_virtual, LW_BRIDGE_SPAN) != 0) {
		printf("ERROR: munmap() failed...\n");
		return(-1);
	}
	close(fd);

	return 0;
}

void write_to_audio_port(double sample) {
	int write = 0;
	while ((write == 0) && !stop) {
		if ((*(audio_base_ptr + 1) & 0xFF00000) && (*(audio_base_ptr + 1) & 0x00FF000)) {
			*(audio_base_ptr + 2) = (int) sample;
			*(audio_base_ptr + 3) = (int) sample;
			write = 1;
		}
	}
}

0 Kudos
2 Replies
vimfulDang
Beginner
259 Views

I found the problem. The sampling rate does not match the hardware's

EBERLAZARE_I_Intel
251 Views

Hi,


Glad you found the fix to your issue, I could not found any specific design example on this, but you may take a look this basic DSP exercise for your future reference:


ftp://ftp.intel.com/pub/fpgaup/pub/Intel_Material/Laboratory_Exercises/Digital_Logic/Verilog/lab12.p...


Reply