Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Readers > Amazon Kindle > Kindle Developer's Corner

Notices

Reply
 
Thread Tools Search this Thread
Old 07-10-2012, 12:05 PM   #76
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
THIS IS THE OLD TAR.GZ FROM THE ORIGINAL TOP POST.
Moved here now.


THIS IS ONLY TESTED ON A K3 - PLEASE USE THE TONES DEMO FOR OTHER MODELS

Usage ./Balsamic ./YourWave.wav

Note that this version will probably not support the plughw device for now.
So stereo waves in sensible rates, I think.

Sorry for the foof.
Attached Files
File Type: gz Balsamic-FIXED-HW-VERSION.tar.gz (695.5 KB, 261 views)

Last edited by twobob; 07-12-2012 at 10:59 PM. Reason: updated details. thanks knc1
twobob is offline   Reply With Quote
Old 07-10-2012, 12:09 PM   #77
knc1
Going Viral
knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.
 
knc1's Avatar
 
Posts: 17,212
Karma: 18210809
Join Date: Feb 2012
Location: Central Texas
Device: No K1, PW2, KV, KOA
Quote:
Originally Posted by twobob View Post
I can't seem to edit the top post right now. (or the second one)
This site package has an edit-rate limiter.
Just wait awhile, it will time-out and let you start editing posts again.
knc1 is offline   Reply With Quote
Old 07-10-2012, 12:29 PM   #78
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
Thanks for the tip

Quote:
Originally Posted by knc1 View Post
This site package has an edit-rate limiter.
Just wait awhile, it will time-out and let you start editing posts again.
Ah will do.
Well, I have these building again. albeit somewhat shonkily.

Time to play with some noises.

EDIT: UPDATED TOP POST.

Last edited by twobob; 07-10-2012 at 02:41 PM. Reason: finally replaced all the broken downloads.
twobob is offline   Reply With Quote
Old 07-10-2012, 07:26 PM   #79
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
Post hmm.. Full duplex with polling is not playing nice. better slow it down

Well. I managed to get my hands on some fairly heavyweight code for full duplex.

Sadly though the initialisation period of the card is making it choke

THE FAIL: straced.
Spoiler:
Code:
// Doing the prep and sync

ioctl(4, SNDRV_PCM_IOCTL_PREPARE, 0xddd18) = 0
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0
ioctl(5, SNDRV_PCM_IOCTL_PREPARE, 0xe8240) = 0
ioctl(5, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8170) = 0
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0
ioctl(4, SNDRV_PCM_IOCTL_START, 0xe8240) = 0

// Run a poll

poll([{fd=4, events=POLLIN|POLLERR|POLLNVAL}, {fd=5, events=POLLOUT|POLLERR|POLLNVAL}], 2, -1) = 1 ([{fd=5, revents=POLLOUT}])
write(1, "demangled poll:  on capture devi"..., 35) = 35
write(1, "demangled poll: POLLOUT  on play"..., 44) = 44
ioctl(5, SNDRV_PCM_IOCTL_WRITEI_FRAMES, 0xbedb6a2c) = 0
ioctl(5, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8170) = 0
write(1, "wrote 160 frames\n", 17)      = 17
poll([{fd=4, events=POLLIN|POLLERR|POLLNVAL}, {fd=5, events=POLLOUT|POLLERR|POLLNVAL}], 2, -1) = 1 ([{fd=5, revents=POLLOUT}])
write(1, "demangled poll:  on capture devi"..., 35) = 35
write(1, "demangled poll: POLLOUT  on play"..., 44) = 44

// And then boom...

ioctl(5, SNDRV_PCM_IOCTL_WRITEI_FRAMES, 0xbedb6a2c) = -1 EPIPE (Broken pipe)
write(2, "XRUN while writing to playback d"..., 51) = 51
ioctl(4, SNDRV_PCM_IOCTL_PREPARE, 0xddd0c) = -1 EBUSY (Device or resource busy)
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0
ioctl(4, SNDRV_PCM_IOCTL_START, 0xe8240) = -1 EBADFD (File descriptor in bad state)
ioctl(4, SNDRV_PCM_IOCTL_PREPARE, 0x1f) = -1 EBUSY (Device or resource busy)
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0
ioctl(4, SNDRV_PCM_IOCTL_START, 0xe8240) = -1 EBADFD (File descriptor in bad state)
write(1, "wrote -32 frames\n", 17)      = 17


This smells to me like unhandled underrun so I'll see if I can get it to double up on the buffer times.

Nice to get some fresh code code to rummage around in.
http://pastebin.com/fCicqctq

EDIT: Even with an enormous period of pcm_period_size=4096 it still dies off after just a few seconds... Perhaps some more rugged error handling is in order.
Spoiler:
Code:
#include <stdio.h>
#include <alsa/asoundlib.h>
#include <string.h>
#include <sched.h>
#include <alloca.h>
#include <stdint.h>

void hexdump(uint8_t *buffer, int len)
{
	int i;
	int addr=0;
	const int bytecount=16;

	fprintf(stderr, "hexdump(): %i bytes\n", len);
	fflush(NULL);

	for (i=0; i<len; i++)
	{
		if ((i % bytecount) == 0)
			fprintf(stderr, "%04x\t", addr);

		fprintf(stderr, "%02x ", buffer[i]);

		if (((i+1) % bytecount) == 0)
		{
			addr += bytecount;
			fprintf(stderr, "\n");
		}
	}

	if (((i+1) % bytecount) != 0)
		fprintf(stderr, "\n");
}

// returns handle of PCM on success, NULL otherwise
snd_pcm_t *setup_pcm(char *device_name, int stream)
{
	int ret;
	snd_pcm_t *handle=NULL;
	snd_pcm_hw_params_t *hwparams=NULL;
	snd_pcm_sw_params_t *swparams=NULL;
	snd_pcm_format_t pcm_format;
	int dir;
	unsigned int pcm_rate_min, pcm_rate_max, pcm_rate, pcm_rate_real;
	snd_pcm_uframes_t pcm_period_size_min, pcm_period_size_max, pcm_period_size;
	snd_pcm_uframes_t pcm_buffer_size_min, pcm_buffer_size_max, pcm_buffer_size, pcm_buffer_size_real;
	snd_pcm_uframes_t start_threshold, stop_threshold;
	snd_pcm_uframes_t avail_min;


	if ((stream != SND_PCM_STREAM_PLAYBACK) && (stream != SND_PCM_STREAM_CAPTURE))
	{
		fprintf(stderr, "invalid stream\n");
		return NULL;
	}

	assert(device_name);

	// open sound card
	if ((ret=snd_pcm_open(&handle, device_name, stream, SND_PCM_NONBLOCK))<0)
	//if ((ret=snd_pcm_open(&handle, device_name, stream, 0))<0)
	{
		fprintf(stderr, "could not open PCM: %s\n", snd_strerror(ret));
		return NULL;
	}

	// auto-alloc and fill hardware params
	snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_hw_params_any(handle, hwparams);

	// set access format
	snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);

	// set audio format
	pcm_format=SND_PCM_FORMAT_S16_LE;
	snd_pcm_hw_params_set_format (handle, hwparams, pcm_format);

	printf("PCM format is %s, %s, %s with %i bits\n",
		snd_pcm_format_signed(pcm_format)? "signed":"unsigned",
		snd_pcm_format_linear(pcm_format)? "linear":"not linear",
		snd_pcm_format_little_endian (pcm_format)? "LE":"BE",
		snd_pcm_format_width(pcm_format));

	// set channels
	snd_pcm_hw_params_set_channels (handle, hwparams, 1);

	// get minimum and maximum supported rates
	dir=0;
	if ((ret=snd_pcm_hw_params_get_rate_min(hwparams, &pcm_rate_min, &dir))<0)
	{
		fprintf(stderr, "could not get minimum supported rate: %s\n", snd_strerror(ret));
		return NULL;
	}
	dir=0;
	if ((ret=snd_pcm_hw_params_get_rate_max(hwparams, &pcm_rate_max, &dir))<0)
	{
		fprintf(stderr, "could not get maximum supported rate: %s\n", snd_strerror(ret));
		return NULL;
	}

	printf("PCM rate %u - %u Hz\n", pcm_rate_min, pcm_rate_max);

	// check rate
	pcm_rate=8000;
	if ((pcm_rate<pcm_rate_min || pcm_rate>pcm_rate_max))
	{
		fprintf(stderr, "PCM rate out of range\n");
		return NULL;
	}

	// check if exact rate is available and set up rate
	dir=0;
	if ((ret=snd_pcm_hw_params_test_rate(handle, hwparams, pcm_rate, dir))<0)
	{
		dir=0;
		pcm_rate_real=pcm_rate;

		// almost always fails - so pick a sensible one.
		if ((ret=snd_pcm_hw_params_set_rate_near(handle, hwparams, &pcm_rate_real, &dir))<0)
		{
			fprintf(stderr, "could not set nearest PCM rate: %s\n", snd_strerror(ret));
			return NULL;
		}

		fprintf(stderr, "exact rate of %u Hz not possible, using nearest possible rate of %u Hz instead\n", pcm_rate, pcm_rate_real);
		pcm_rate=pcm_rate_real;
	}
	else
	{
		dir=0;
		if ((ret=snd_pcm_hw_params_set_rate(handle, hwparams, pcm_rate, dir))<0)
		{
			fprintf(stderr, "could not set up PCM rate: %s\n", snd_strerror(ret));
			return NULL;
		}
	}

	// get minimum and maximum supported period size
	dir=0;
	if ((ret=snd_pcm_hw_params_get_period_size_min(hwparams, &pcm_period_size_min, &dir))<0)
	{
		fprintf(stderr, "could not get minimum supported period size: %s\n", snd_strerror(ret));
		return NULL;
	}
	dir=0;
	if ((ret=snd_pcm_hw_params_get_period_size_max(hwparams, &pcm_period_size_max, &dir))<0)
	{
		fprintf(stderr, "could not get maximum supported period size: %s\n", snd_strerror(ret));
		return NULL;
	}

	printf("PCM period size: %lu - %lu\n", pcm_period_size_min, pcm_period_size_max);

	// check period size
//	pcm_period_size=160;  This is tiny for a kindle
	pcm_period_size=4096;
	if ((pcm_period_size<pcm_period_size_min || pcm_period_size>pcm_period_size_max))
	{
		fprintf(stderr, "PCM period size out of range\n");
		return NULL;
	}

	// check if exact period size is available
	dir=0;
	if ((ret=snd_pcm_hw_params_test_period_size(handle, hwparams, pcm_period_size, dir))<0)
	{
		fprintf(stderr, "requested period size not available: %s\n", snd_strerror(ret));
		return NULL;
	}

	// set up period size
	dir=0;
	if ((ret=snd_pcm_hw_params_set_period_size(handle, hwparams, pcm_period_size, dir))<0)
	{
		fprintf(stderr, "could not set up PCM rate: %s\n", snd_strerror(ret));
		return NULL;
	}

	// get minimum and maximum supported buffer size
	if ((ret=snd_pcm_hw_params_get_buffer_size_min(hwparams, &pcm_buffer_size_min))<0)
	{
		fprintf(stderr, "could not get minimum supported buffer size: %s\n", snd_strerror(ret));
		return NULL;
	}
	if ((ret=snd_pcm_hw_params_get_buffer_size_max(hwparams, &pcm_buffer_size_max))<0)
	{
		fprintf(stderr, "could not get maximum supported buffer size: %s\n", snd_strerror(ret));
		return NULL;
	}

	printf("PCM buffer size: %lu - %lu\n", pcm_buffer_size_min, pcm_buffer_size_max);

	// check buffer size
	// buffer size: 2*period_size with given format and 1 channel (mono)
	pcm_buffer_size=pcm_period_size*snd_pcm_format_size(pcm_format, 1)*2;
	printf("calculated buffer size: %lu\n", pcm_buffer_size);
	if ((pcm_buffer_size<pcm_buffer_size_min || pcm_buffer_size>pcm_buffer_size_max))
	{
		fprintf(stderr, "PCM period size out of range\n");
		return NULL;
	}

	// check if exact buffer size is available and set up buffer size
	if ((ret=snd_pcm_hw_params_test_buffer_size(handle, hwparams, pcm_buffer_size))<0)
	{
		pcm_buffer_size_real=pcm_buffer_size;
		if ((ret=snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &pcm_buffer_size_real))<0)
		{
			fprintf(stderr, "could not set nearest buffer size: %s\n", snd_strerror(ret));
			return NULL;
		}

		fprintf(stderr, "exact buffer size of %lu bytes not possible, using nearest possible buffer size %lu instead\n",
			pcm_buffer_size, pcm_buffer_size_real);
		pcm_buffer_size=pcm_buffer_size_real;
	}
	else
	{
		if ((ret=snd_pcm_hw_params_set_buffer_size(handle, hwparams, pcm_buffer_size))<0)
		{
			fprintf(stderr, "could not set PCM buffer size: %s\n", snd_strerror(ret));
			return NULL;
		}
	}

	// set up configured hw params
	if ((ret=snd_pcm_hw_params(handle, hwparams))<0)
	{
		fprintf(stderr, "could not set up hardware params: %s\n", snd_strerror(ret));
		return NULL;
	}

	// alloc and fill software params
	snd_pcm_sw_params_alloca (&swparams);
	snd_pcm_sw_params_current (handle, swparams);

	if ((ret=snd_pcm_sw_params_get_avail_min(swparams, &avail_min))<0)
	{
		fprintf(stderr, "could not get current avail_min setting: %s\n", snd_strerror(ret));
		return NULL;
	}

	printf("avail min: %lu\n", avail_min);

	// when to consider the device to be ready for the next data transfer operation
	if ((ret=snd_pcm_sw_params_set_avail_min(handle, swparams, pcm_period_size))<0)
	{
		fprintf(stderr, "could not set avail_min: %s\n", snd_strerror(ret));
		return NULL;
	}

	// start threshold
	//start_threshold = (double)pcm_rate * (1/1000000);
	start_threshold = pcm_period_size;
	printf("start threshold: %lu frames\n", start_threshold);
	if ((ret=snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold))<0)
	{
		fprintf(stderr, "could not set start threshold: %s\n", snd_strerror(ret));
		return NULL;
	}


	// stop threshold
	stop_threshold=2*pcm_period_size;
	printf("stop threshold: %lu frames\n", stop_threshold);
	if ((ret=snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold))<0)
	{
		fprintf(stderr, "could not set stop threshold: %s\n", snd_strerror(ret));
		return NULL;
	}

	// set software params
	if ((ret=snd_pcm_sw_params(handle, swparams))<0)
	{
		fprintf(stderr, "could not set sw params: %s\n", snd_strerror(ret));
		return NULL;
	}


	return handle;
}

int main(int argc, char **argv)
{
	struct sched_param schp;
	char *device_name=NULL;
	snd_pcm_t *capture_device=NULL, *playback_device=NULL;
	int capture_pollfd_count, playback_pollfd_count, pollfd_count;
	int ret;
	struct pollfd poll_fds[2];
	uint8_t buffer[160*2];
	int i;
	snd_pcm_state_t state;
	snd_pcm_t *device_handle;
	unsigned short revents;

	if (argc != 2)
	{
		printf("Usage: %s <audio device name>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	device_name=argv[1];

	// try to get high scheduler priority
	memset(&schp, 0, sizeof (schp));
	schp.sched_priority = sched_get_priority_max(SCHED_FIFO);

	if (sched_setscheduler (0, SCHED_FIFO, &schp)<0)
	{
		perror("could not sched_setscheduler");
	}

	// open and configure capture device
	if ((capture_device=setup_pcm(device_name, SND_PCM_STREAM_CAPTURE))==NULL)
	{
		fprintf(stderr, "could not open and set up capture device %s\n", device_name);
		exit(EXIT_FAILURE);
	}

	if ((playback_device=setup_pcm(device_name, SND_PCM_STREAM_PLAYBACK))==NULL)
	{
		fprintf(stderr, "could not open and set up capture device %s\n", device_name);
		exit(EXIT_FAILURE);
	}

	/*
	// try to link capture and playback device so that they start/stop/prepare in sync
	if ((linked=snd_pcm_link(capture_device, playback_device))<0)
	{
		fprintf(stderr, "could not link capture and playback device: %s\n", snd_strerror(linked));
	}
	*/

	// get poll info
	capture_pollfd_count=snd_pcm_poll_descriptors_count(capture_device);
	playback_pollfd_count=snd_pcm_poll_descriptors_count(playback_device);
	pollfd_count=capture_pollfd_count+playback_pollfd_count;

	printf("capture fds: %i, playback fds: %i\n", capture_pollfd_count, playback_pollfd_count);"A Minimal Interrupt-Driven Program"

	assert(capture_pollfd_count==1 && playback_pollfd_count==1);

	// set up poll struct
	memset(poll_fds, 0x00, sizeof(poll_fds));
	snd_pcm_poll_descriptors(capture_device, &poll_fds[0], capture_pollfd_count);
	snd_pcm_poll_descriptors(playback_device, &poll_fds[1], playback_pollfd_count);

	printf("capture poll fd: %i, playback poll fd: %i\n", poll_fds[0].fd, poll_fds[1].fd);
	printf("capture struct: fd: %i, events: %s%s%s, revents: %i\n",
		poll_fds[0].fd,
		(poll_fds[0].events & POLLIN) ? "POLLIN ":"",
		(poll_fds[0].events & POLLOUT) ? "POLLOUT ":"",
		(poll_fds[0].events & POLLERR) ? "POLLERR ":"",
		poll_fds[0].revents);
	printf("playback struct: fd: %i, events: %s%s%s, revents: %i\n",
		poll_fds[1].fd,
		(poll_fds[1].events & POLLIN) ? "POLLIN ":"",
		(poll_fds[1].events & POLLOUT) ? "POLLOUT ":"",
		(poll_fds[1].events & POLLERR) ? "POLLERR ":"",
		poll_fds[1].revents);

	// prepare capture PCM
	if ((ret=snd_pcm_prepare(capture_device))<0)
	{
		fprintf(stderr, "could not prepare capture device: %s\n", snd_strerror(ret));
		exit(EXIT_FAILURE);
	}

	// prepare playback PCM
	if ((ret=snd_pcm_prepare(playback_device))<0)
	{
		fprintf(stderr, "could not prepare playback device: %s\n", snd_strerror(ret));
		exit(EXIT_FAILURE);
	}

	// start capture device
	if ((ret=snd_pcm_start(capture_device))<0)
	{
		fprintf(stderr, "could not start capture device: %s\n", snd_strerror(ret));
		exit(EXIT_FAILURE);
	}

	memset(buffer, 0x00, sizeof(buffer));

	// read samples from capture device and write them to the playback device
	while (1)
	{
		// poll on both devices
		poll(poll_fds, pollfd_count, -1);

		for (i=0; i<pollfd_count; i++)
		{

			if (i==0)
				device_handle=capture_device;
			else
				device_handle=playback_device;

			// get demangled revent
			if ((ret=snd_pcm_poll_descriptors_revents(device_handle, &poll_fds[i], 1, &revents))<0)
			{
				fprintf(stderr, "could not snd_pcm_poll_descriptors_revents: %s\n", snd_strerror(ret));
				exit(EXIT_FAILURE);
			}

			printf("demangled poll: %s%s%s on %s device\n",
				(revents & POLLERR)? "POLLERR ":"",
				(revents & POLLIN)? "POLLIN ":"",
				(revents & POLLOUT)? "POLLOUT ":"",
				(i==0)? "capture":"playback");

			// check if there was an error
			if (revents & POLLERR)
			{
				state=snd_pcm_state(device_handle);

				switch(state)
				{
					case	SND_PCM_STATE_XRUN:
													fprintf(stderr, "XRUN on %s device\n",
														(poll_fds[i].revents & POLLOUT) ? "playback" : "capture");

													// restart
													snd_pcm_prepare(device_handle);
													snd_pcm_start(device_handle);
													break;
					default:
													fprintf(stderr, "unknown state (%i) on %s device\n",
														state, (poll_fds[i].revents & POLLOUT) ? "playback" : "capture");
				}
			}

			// check for new input data
			if (revents & POLLIN)
			{
				if ((ret=snd_pcm_readi(capture_device, buffer, 160))<0)
				{
					if (ret == -EPIPE)
					{
						fprintf(stderr, "XRUN while reading from capture device: %s\n", snd_strerror(ret));
						snd_pcm_prepare(capture_device);
						snd_pcm_start(capture_device);
					}
					else
					{
						fprintf(stderr, "could not read from capture device: %s\n", snd_strerror(ret));
						exit(EXIT_FAILURE);
					}
				}

				printf("read %i frames\n", ret);
				assert(ret==160);

				hexdump(buffer, ret*2);
			}

			// check if we can write the buffer to the playback device
			if (revents & POLLOUT)
			{
				if ((ret=snd_pcm_writei(playback_device, buffer, 160))<0)
				{
					if (ret == -EPIPE)
					{
						fprintf(stderr, "XRUN while writing to playback device: %s\n", snd_strerror(ret));
						snd_pcm_prepare(capture_device);
						snd_pcm_start(capture_device);

					}
					else
					{
						fprintf(stderr, "could not write to playback device: %s\n", snd_strerror(ret));
						exit(EXIT_FAILURE);
					}
				}

				printf("wrote %i frames\n", ret);
				assert(ret==160);

			//	hexdump(buffer, ret*2);
			}
		}
	} // while(1)

	// never reached
	exit(EXIT_SUCCESS);
}

Last edited by twobob; 07-10-2012 at 08:03 PM. Reason: Added further failure :)
twobob is offline   Reply With Quote
Old 07-10-2012, 08:01 PM   #80
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
More code - More fail:

Another interrupt driven example that fails:

http://equalarea.com/paul/alsa-audio.html

Title "A Minimal Interrupt-Driven Program" ( 3rd on page)

THE FAIL: straced.
Spoiler:
Code:
ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0xbed9eb48) = 0         
ioctl(4, SNDRV_PCM_IOCTL_PREPARE, 0)    = 0                          
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0                       
ioctl(4, SNDRV_PCM_IOCTL_SW_PARAMS, 0xe8170) = 0              
ioctl(4, SNDRV_PCM_IOCTL_PREPARE, 0)    = 0
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0
poll([{fd=4, events=POLLOUT|POLLERR|POLLNVAL}], 1, 1000) = 0 (Timeout)
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
write(1, "playback callback called with 40"..., 42) = 42
ioctl(4, SNDRV_PCM_IOCTL_WRITEI_FRAMES, 0xbed9eb7c) = 0               
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0             
poll([{fd=4, events=POLLOUT|POLLERR|POLLNVAL}], 1, 1000) = 1 ([{fd=4,
ioctl(4, SNDRV_PCM_IOCTL_SYNC_PTR, 0xe8240) = 0
write(2, "poll failed (No such device or a"..., 40) = 40
ioctl(4, SNDRV_PCM_IOCTL_DROP, 0xdbe3c) = 0
ioctl(4, SNDRV_PCM_IOCTL_HW_FREE, 0x2b018) = 0


The Code
Spoiler:
Code:
	#include <stdio.h>
	#include <stdlib.h>
	#include <errno.h>
	#include <poll.h>
	#include <alsa/asoundlib.h>

	snd_pcm_t *playback_handle;
	short buf[4096];

	int
	playback_callback (snd_pcm_sframes_t nframes)
	{
		int err;

		printf ("playback callback called with %u frames\n", nframes);

		/* ... fill buf with data ... */

		if ((err = snd_pcm_writei (playback_handle, buf, nframes)) < 0) {
			fprintf (stderr, "write failed (%s)\n", snd_strerror (err));
		}

		return err;
	}

	main (int argc, char *argv[])
	{

		snd_pcm_hw_params_t *hw_params;
		snd_pcm_sw_params_t *sw_params;
		snd_pcm_sframes_t frames_to_deliver;
		int nfds;
		int err;
		struct pollfd *pfds;

		if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
			fprintf (stderr, "cannot open audio device %s (%s)\n",
				 argv[1],
				 snd_strerror (err));
			exit (1);
		}

		if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
			fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
			fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
   //     printf("here");
		if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
			fprintf (stderr, "cannot set access type (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
			fprintf (stderr, "cannot set sample format (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		if ((err = snd_pcm_hw_params_set_rate (playback_handle, hw_params, 44100, 0)) < 0) {
			fprintf (stderr, "cannot set sample rate (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
			fprintf (stderr, "cannot set channel count (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
			fprintf (stderr, "cannot set parameters (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		snd_pcm_hw_params_free (hw_params);

		/* tell ALSA to wake us up whenever 4096 or more frames
		   of playback data can be delivered. Also, tell
		   ALSA that we'll start the device ourselves.
		*/

		if ((err = snd_pcm_sw_params_malloc (&sw_params)) < 0) {
			fprintf (stderr, "cannot allocate software parameters structure (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
		if ((err = snd_pcm_sw_params_current (playback_handle, sw_params)) < 0) {
			fprintf (stderr, "cannot initialize software parameters structure (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
		if ((err = snd_pcm_sw_params_set_avail_min (playback_handle, sw_params, 4096)) < 0) {
			fprintf (stderr, "cannot set minimum available count (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
		if ((err = snd_pcm_sw_params_set_start_threshold (playback_handle, sw_params, 0U)) < 0) {
			fprintf (stderr, "cannot set start mode (%s)\n",
				 snd_strerror (err));
			exit (1);
		}
		if ((err = snd_pcm_sw_params (playback_handle, sw_params)) < 0) {
			fprintf (stderr, "cannot set software parameters (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		/* the interface will interrupt the kernel every 4096 frames, and ALSA
		   will wake up this program very soon after that.
		*/

		if ((err = snd_pcm_prepare (playback_handle)) < 0) {
			fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
				 snd_strerror (err));
			exit (1);
		}

		while (4) {

			/* wait till the interface is ready for data, or 1 second
			   has elapsed.
			*/

			if ((err = snd_pcm_wait (playback_handle, 1000)) < 0) {
			        fprintf (stderr, "poll failed (%s)\n", strerror (errno));
			        break;
			}

			/* find out how much space is available for playback data */

			if ((frames_to_deliver = snd_pcm_avail_update (playback_handle)) < 0) {
				if (frames_to_deliver == -EPIPE) {
					fprintf (stderr, "an xrun occured\n");
					break;
				} else {
					fprintf (stderr, "unknown ALSA avail update return value (%d)\n",
						 frames_to_deliver);
					break;
				}
			}

			frames_to_deliver = frames_to_deliver > 4096 ? 4096 : frames_to_deliver;

			/* deliver the data */

			if (playback_callback (frames_to_deliver) != frames_to_deliver) {
			        fprintf (stderr, "playback callback failed\n");
				break;
			}
		}

		snd_pcm_close (playback_handle);
		exit (0);
	}

So issues with that one... Polling doesn't look like it wants to play nice.
It's only an example. I prefer the previous posts design in oh so many ways.

Last edited by twobob; 07-10-2012 at 08:06 PM. Reason: Added Code ref
twobob is offline   Reply With Quote
Old 07-10-2012, 08:14 PM   #81
knc1
Going Viral
knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.knc1 ought to be getting tired of karma fortunes by now.
 
knc1's Avatar
 
Posts: 17,212
Karma: 18210809
Join Date: Feb 2012
Location: Central Texas
Device: No K1, PW2, KV, KOA
Quote:
Originally Posted by twobob View Post
So issues with that one... Polling doesn't look like it wants to play nice.
It's only an example. I prefer the previous posts design in oh so many ways.
Code:
frames_to_deliver = frames_to_deliver > 4096 ? 4096 : frames_to_deliver;
First, do a quick re-write of that statement then re-run it.

Why?
There was a recent GCC bug fixed in the ARM arch for "wrong code generation" from that construct.
Quicker to just re-write it and re-test than run down all of the who/what/when/why of the bug.
knc1 is offline   Reply With Quote
Old 07-10-2012, 08:53 PM   #82
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
Posix signals for audio - polling not great

Using posix signals for Linux Audio IO is evil by all accounts - so best avoid Async stuff.
(http://mailman.alsa-project.org/pipe...ay/008030.html)

I'm not getting much mileage from the polling either. possibly need more error handling
It's supposedly the better option. sigh.

Would be nice to work out which are the more solid transfer methods.

Here's some fairly helpful Do's and Dont's, syndicated with permission (as indicated on the page http://0pointer.de/blog/projects/guide-to-sound-apis ) here

Spoiler:
Here's a list of DOS and DONTS in the ALSA API if you care about that you application stays future-proof and works fine with non-hardware backends or backends for user-space sound drivers such as Bluetooth and FireWire audio. Some of these recommendations apply for people using the full ALSA API as well, since some functionality should be considered obsolete for all cases.

If your application's code does not follow these rules, you must have a very good reason for that. Otherwise your code should simply be considered broken!

DONTS:

* Do not use "async handlers", e.g. via snd_async_add_pcm_handler() and friends. Asynchronous handlers are implemented using POSIX signals, which is a very questionable use of them, especially from libraries and plugins. Even when you don't want to limit yourself to the safe ALSA subset it is highly recommended not to use this functionality.

* Do not parse the ALSA configuration file yourself or with any of the ALSA functions such as snd_config_xxx(). If you need to enumerate audio devices use snd_device_name_hint() (and related functions). That is the only API that also supports enumerating non-hardware audio devices and audio devices with drivers implemented in userspace.

* Do not parse any of the files from /proc/asound/. Those files only include information about kernel sound drivers -- user-space plugins are not listed there. Also, the set of kernel devices might differ from the way they are presented in user-space. (i.e. sub-devices are mapped in different ways to actual user-space devices such as surround51 an suchlike.

* Do not rely on stable device indexes from ALSA. Nowadays they depend on the initialization order of the drivers during boot-up time and are thus not stable.

* Do not use the snd_card_xxx() APIs. For enumerating use snd_device_name_hint() (and related functions). snd_card_xxx() is obsolete. It will only list kernel hardware devices. User-space devices such as sound servers, Bluetooth audio are not included. snd_card_load() is completely obsolete in these days.

* Do not hard-code device strings, especially not hw:0 or plughw:0 or even dmix -- these devices define no channel mapping and are mapped to raw kernel devices. It is highly recommended to use exclusively default as device string. If specific channel mappings are required the correct device strings should be front for stereo, surround40 for Surround 4.0, surround41, surround51, and so on. Unfortunately at this point ALSA does not define standard device names with channel mappings for non-kernel devices. This means default may only be used safely for mono and stereo streams. You should probably prefix your device string with plug: to make sure ALSA transparently reformats/remaps/resamples your PCM stream for you if the hardware/backend does not support your sampling parameters natively.

* Do not assume that any particular sample type is supported except the following ones: U8, S16_LE, S16_BE, S32_LE, S32_BE, FLOAT_LE, FLOAT_BE, MU_LAW, A_LAW. (The kindle also does S24_LE, and S20_3LE)

* Do not use snd_pcm_avail_update() for synchronization purposes. It should be used exclusively to query the amount of bytes that may be written/read right now. Do not use snd_pcm_delay() to query the fill level of your playback buffer. It should be used exclusively for synchronisation purposes. Make sure you fully understand the difference, and note that the two functions return values that are not necessarily directly connected!

* Do not assume that the mixer controls always know dB information.

* Do not assume that all devices support MMAP style buffer access.

* Do not assume that the hardware pointer inside the (possibly mmaped) playback buffer is the actual position of the sample in the DAC. There might be an extra latency involved.

* Do not try to recover with your own code from ALSA error conditions such as buffer under-runs. Use snd_pcm_recover() instead.

* Do not touch buffering/period metrics unless you have specific latency needs. Develop defensively, handling correctly the case when the backend cannot fulfill your buffering metrics requests. Be aware that the buffering metrics of the playback buffer only indirectly influence the overall latency in many cases. i.e. setting the buffer size to a fixed value might actually result in practical latencies that are much higher.

* Do not assume that snd_pcm_rewind() is available and works and to which degree.

* Do not assume that the time when a PCM stream can receive new data is strictly dependant on the sampling and buffering parameters and the resulting average throughput. Always make sure to supply new audio data to the device when it asks for it by signalling "writability" on the fd. (And similarly for capturing)

* Do not use the "simple" interface snd_spcm_xxx().

* Do not use any of the functions marked as "obsolete".

* Do not use the timer, midi, rawmidi, hwdep subsystems.

DOS:

* Use snd_device_name_hint() for enumerating audio devices.

* Use snd_smixer_xx() instead of raw snd_ctl_xxx().

* For synchronization purposes use snd_pcm_delay().

* For checking buffer playback/capture fill level use snd_pcm_update_avail().

* Use snd_pcm_recover() to recover from errors returned by any of the ALSA functions.

* If possible use the largest buffer sizes the device supports to maximize power saving and drop-out safety. Use snd_pcm_rewind() if you need to react to user input quickly.

Last edited by twobob; 07-10-2012 at 09:12 PM. Reason: added refs.
twobob is offline   Reply With Quote
Old 07-10-2012, 08:55 PM   #83
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
Ternary form no good?

Quote:
Originally Posted by knc1 View Post
Code:
frames_to_deliver = frames_to_deliver > 4096 ? 4096 : frames_to_deliver;
First, do a quick re-write of that statement then re-run it.

Why?
There was a recent GCC bug fixed in the ARM arch for "wrong code generation" from that construct.
Quicker to just re-write it and re-test than run down all of the who/what/when/why of the bug.
Ah. Okay thanks. Ternary to be binned. noted.

I'll give it another pop then

I went with

Code:
if (frames_to_deliver > 4096)
		{frames_to_deliver = 4096;}
Seemed rather pointless as a construct all in.

EDIT: It didn't help, but good catch anyways. Frankly I'm not so keen on this second example.
The first one is much more robust.

Last edited by twobob; 07-10-2012 at 09:04 PM. Reason: added reworked code
twobob is offline   Reply With Quote
Old 07-10-2012, 09:16 PM   #84
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
4 results. Really?

http://code.google.com/query/#q=alsa

returns 4 results.

That's pitiful
twobob is offline   Reply With Quote
Old 07-10-2012, 10:10 PM   #85
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
More Nice things:

https://lwn.net/Articles/495612/ Has an article on this years Linux Audio Conference.
Which info is like finding hens teeth might I add. In addition this is usually a paid for link.
As a one-off this particular article is free to read. Happy days.
(They also have a run-down of linux plugins here https://lwn.net/Articles/501978/ which code glean some inspriration)

https://ccrma.stanford.edu/software have a few audio code goodies to get your head around.
(and they know a thing or two)

Time for bed.
twobob is offline   Reply With Quote
Old 07-10-2012, 10:39 PM   #86
twobob
( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Tır
twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.twobob ought to be getting tired of karma fortunes by now.
 
twobob's Avatar
 
Posts: 6,586
Karma: 6299993
Join Date: Jun 2012
Location: uti gratia usura (Yao ying da ying; Mo ying da yieng)
Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch
Looks like the tones demo I top posted uses about 35 - 40% of the cpu just to do the demo...



Would like to see this run side-by-side geekmasters code now to see if the device can handle it

Clearly some optimisation to be done.
twobob is offline   Reply With Quote
Old 07-11-2012, 02:34 AM   #87
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773670
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Re: never touching system files, you can temporarily replace a system file with a modified copy using bind mount, like I did in my tccmake script. You would need to launch you app with a script that does the bind mount before your app, then unmounts after.
geekmaster is offline   Reply With Quote
Old 07-11-2012, 02:42 AM   #88
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773670
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by twobob View Post
http://code.google.com/query/#q=alsa

returns 4 results.

That's pitiful
It only returns 3 results for me, so either they removed one, or Google Code customizes your output like Google does for general web searches.
geekmaster is offline   Reply With Quote
Old 07-11-2012, 02:54 AM   #89
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773670
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Quote:
Originally Posted by twobob View Post
Looks like the tones demo I top posted uses about 35 - 40% of the cpu just to do the demo...
...
Would like to see this run side-by-side geekmasters code now to see if the device can handle it

Clearly some optimisation to be done.
That looks like a fun little project. I often find that interleaving the code into one loop uses less CPU that trying to multiprocess it as two apps, or other coprocessing methods that rely on two simultaneous loops.

I like the coroutines method by Simon Tatham (the PuTTY guy), which allows logically interleaving control flow while maintaining visual separation: http://www.chiark.greenend.org.uk/~s...oroutines.html
We could use that to interleave the video and audio code inside one control loop.

Simon Tatham also has a nice collection of simple Java games that might make nice kindlets: http://www.chiark.greenend.org.uk/~sgtatham/puzzles/

Anyway, I am looking forward to adding some some code to gmplay, to play gmv video files that contain interleaved audio and video (using your code above). Thanks. Just need to get caught up at work a bit first before I take some "educational play time".

Re: running side-by-side, you can do that by opening two SSH shells...

Last edited by geekmaster; 07-11-2012 at 04:52 AM.
geekmaster is offline   Reply With Quote
Old 07-11-2012, 03:51 AM   #90
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773670
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
Okay, I opened up three SSH sessions on my K3. I ran htop in one. Then I ran gmplay with the Howard Lloyd clock video. Htop reported gmplay using 88% CPU. Then I ran tones, which made gmplay get jerky (slower framerate) and dropped gmplay to about 37% CPU, while tones took 40% CPU.

After about 20 seconds, tones aborted with "Write error: Input/output error", then gmplay jumped back up to 88%. I think a lot of that time is spent in system calls (especially on the K3, which does not return from the eink update until complete). gmplay spends a significant amount of time sleeping on the K4 or K5 (while the K3 is inside the system calls). Perhaps the K3 eink drivers use a wait loop or spinlock, consuming CPU overhead.

Last edited by geekmaster; 07-11-2012 at 04:07 AM.
geekmaster is offline   Reply With Quote
Reply

Tags
stupid root mistakes


Forum Jump


All times are GMT -4. The time now is 12:55 PM.


MobileRead.com is a privately owned, operated and funded community.