LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-25-2004, 01:43 PM   #1
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Costa Rica
Distribution: Kubuntu, Debian, Knoppix
Posts: 2,092
Blog Entries: 1

Rep: Reputation: 90
Question I wonder why a program I made with streams is taking so much memory


Hi, guys!

I made this morning a program to normalize cd raw data before I pass it to lame to encode it into mp3.

I read the cd data with cdparanoia, pipe it into my normalizing app, I save all the input data in memory while i'm getting the highest value in the piece, then I multiply it and pipe it to lame.

If i'm not wrong, CD data is about 9 mb per minut of playing..... but I have noticed that while buffering the CD information in my application, the app is taking 3 to 4 times that amount of memory.

How can that happen?

Here is my normalization code..... It's not bug-proof. Only some checking is done:


Code:
// normalization program

/*
	Usage:
	normalize [min=5] [max=50]
	given values are in %
*/

#include <stdio.h>
#include <string.h>

int min = 0;
int max = 100;

float factor; // factor to use on input to get output

short maxValue = 0;

typedef struct {
	short channel[2];
	void * next; // pointer to node
} node;

int main(int argc, char ** argv) {
	int leido;		
	int i;
	
	for (i = 1; i < argc; i++) {
		// go through arguments
		char * argument = argv[i];
		// min
		if (strstr(argument, "min") == argument) {
			// minimo
			if (argument[3] != '=' || argument[4] == ' ') {
				fprintf(stderr, "El minimo se debe establecer \"min=valor\"\n");
				exit(1);
			}
			min = atoi(&(argument[4]));
			
			if (min < 0) {
				fprintf(stderr, "El minimo no puede ser menor que 0!\n");
				exit(1);
			}
			if (min > 100) {
				fprintf(stderr, "El minimo no puede ser mayor que 100!\n");
				exit(1);
			}
		} else if (strstr(argument, "max") == argument) {
			// maximo
			if (argument[3] != '=' || argument[4] == ' ') {
				fprintf(stderr, "El maximo se debe establecer \"max=valor\"\n");
				exit(1);
			}
			max = atoi(&(argument[4]));
			
			if (max < 0) {
				fprintf(stderr, "El maximo no puede ser menor que 0!\n");
				exit(1);
			}
			if (max > 100) {
				fprintf(stderr, "El maximo no puede ser mayor que 100!\n");
				exit(1);
			}
		}
	}
	
	if (min > max) {
		fprintf(stderr, "El minimo no puede ser mayor que el maximo!\n");
		exit(1);
	}
	
	fprintf(stderr, "Niveles usados: min=%d max=%d\n", min, max); 
	
	node * newNode;
	node list;
	list.next = NULL;
	node * lastNode;

	do {
		newNode = (node *) malloc(sizeof(node));
		leido = fread(newNode, 1, 4, stdin);
		if (leido == 4) {
			newNode->next = NULL;
			for (i = 0; i < 2; i++) {
				short channel = newNode->channel[i];
				if (abs(channel) > maxValue) {
					maxValue = abs(channel);
					fprintf(stderr, "New Max Value = %d (%d)\n", maxValue, channel);
				}
			}
			if (list.next == NULL) {
				list.next = (void *) newNode;
			} else {
				lastNode->next = (void *) newNode;
			}
			lastNode = newNode;
		} else {
			// calculo del factor
			float nivelMaximo = (float) maxValue / 0x7fff * 100;
			fprintf(stderr, "nivel alcanzado: %f\n", nivelMaximo);
			factor = 1;
			
			if (nivelMaximo < min) {
				factor = (float) min / nivelMaximo;
			}
			
			if (nivelMaximo > max)  {
				factor = (float) max / nivelMaximo;
				//fprintf(stderr, "cambie el maximo\n");
			}
				
			fprintf(stderr, "Factor usado: %f\n", factor);
			// se termino el flujo
			lastNode = list.next;
			while (lastNode != NULL)  {
				// process list
				//printf("%c%c", (short) (lastNode->channel[0]*0.5), (short) (lastNode->channel[1]*0.5));
				lastNode -> channel[0] *= factor;
				lastNode -> channel[1] *= factor;
				fwrite(lastNode, 1, 4, stdout);
				newNode = lastNode;
				lastNode = lastNode -> next;
				free(newNode); // release memory from node already used
			}
			if (leido != 0) {
				printf("Parece que el flujo de entrada no correspondiera a un flujo de 16 bits por canal de 2 canales :(\n");
			}
		}
	} while (leido == 4);
}
so..... why could it be taking 3 or 4 times the memory it should?

Thanks for reading.

PS
How can I get my code justified the way I have it in my original code( with tabs)... always I paste something here, all lines of code are next to the left border.. instead of keeping the tabs.

Last edited by eantoranz; 04-25-2004 at 02:48 PM.
 
Old 04-25-2004, 01:49 PM   #2
rkef
Member
 
Registered: Mar 2004
Location: bursa
Posts: 110

Rep: Reputation: 15
Sorry, can't help with your main question. But as far as pasting code here, you should put it between code tags. Like this (but with [] instead of <>):
<code>
#include <unistd>

int main(void)
{
// ...
exit(0);
}
</code>

Last edited by rkef; 04-25-2004 at 01:50 PM.
 
Old 04-25-2004, 02:41 PM   #3
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Costa Rica
Distribution: Kubuntu, Debian, Knoppix
Posts: 2,092

Original Poster
Blog Entries: 1

Rep: Reputation: 90
Got the ext formatting trick. Thank you, man!

How about the memory problem? anybode knows?
 
Old 04-25-2004, 03:10 PM   #4
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Costa Rica
Distribution: Kubuntu, Debian, Knoppix
Posts: 2,092

Original Poster
Blog Entries: 1

Rep: Reputation: 90
I was forgetting about the pointer I'm using to make the list... so each sample is 8 bytes long.... that makes it 20 mb / sec.... that's pretty much what the program is taking.... therefore I think it's solved (i think my math wasn't so right in the beginig).

Thanks anyway, guys..... enjoy the code anyway.
 
Old 04-26-2004, 06:33 AM   #5
gamehack
Member
 
Registered: Jun 2003
Location: Sevenoaks, UK
Distribution: Ubuntu
Posts: 183

Rep: Reputation: 30
As far as I know, 1 min of CD data is about 10 mb
 
Old 04-30-2004, 07:37 PM   #6
eantoranz
Senior Member
 
Registered: Apr 2003
Location: Costa Rica
Distribution: Kubuntu, Debian, Knoppix
Posts: 2,092

Original Poster
Blog Entries: 1

Rep: Reputation: 90
OK, guys... found the problem.

When I took every sample (16 bits per channel * 2) I created a node of data and added it to the list. I made the list through pointers... and the pointers were taking a horrendous amount of memory (44100 pointers per second).

I changed the approach and decided to make a list node able to carry samples for a second... so I have only a single pointer per second of cd sound.

Now it takes almost as little memory as the CD data itself (remember.. a pointer per every second).

Hope it helps you.... and if you want to get the code, please, let me know.

Thanks!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
are the consoles already taking up system memory? DJOtaku Linux - General 5 10-31-2005 03:52 PM
Memory Managment Made Easy Newbie85 Linux - Newbie 1 02-28-2005 12:51 PM
x is taking alot of memory Smokey Slackware 3 02-07-2005 04:07 PM
Why is XFree taking so much memory? eantoranz Linux - Software 15 10-27-2004 12:59 PM
Memory Leak when using memory debugging C program on SuSE SLES8 babalina Linux - Distributions 0 10-06-2003 09:39 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:42 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration