All of lore.kernel.org
 help / color / mirror / Atom feed
* Help needed. (long)
@ 2003-05-19  9:40 Eliot Blennerhassett
  2003-05-19 16:10 ` PCI problem Giuliano Pochini
  2003-05-19 16:34 ` Help needed. (long) Takashi Iwai
  0 siblings, 2 replies; 5+ messages in thread
From: Eliot Blennerhassett @ 2003-05-19  9:40 UTC (permalink / raw)
  To: alsa-devel; +Cc: eliot

Greetings,

(Aside: I still can only post to this list via a web mailer, so apologies if the
formatting is messed up. Still looking for a way to find out what is wrong with
my POP mailer.
Also I'd like to attach a file, but I cant...)

Whereas I have pressed the reset button for the Nth time,
Whereas I have little experience in driver writing,
Whereas I am going around in circles,

Therefore, I have resolved to swallow my pride and subject my code to the
scrutiny of my superiors (in terms of ALSA driver knowledge at least...)

If there is someone out there who can answer the following questions, and is
also interested and able in developing the driver further in exchange for an
AudioScience card (6114, 6122, or 5111)please let me know.

1) Am I understanding this correctly?
I see this kind of sequence:
prepare
copy
copy
copy
trigger(start)

(driver calls period_elapsed)
pointer
copy
pointer
pointer
copy
pointer
pointer
pointer
trigger(stop)


The middle-layer expects that the pointer will be increasing (modulo the buffer
size).
It expects that it should have increased by (at least) the period every time
snd_pcm_period_elapsed is called.

When the middle-layer enters the draining state, the copy callback isn't called
any more.
What is supposed to happen to the pointer now, and how many more times is
period_elapsed expected to be called?

I ask because on our cards when data runs out, the 'pointer' stops moving.
When this happens, and I don't call period_elapsed, then aplay hangs for a while
before erroring out - "failed to exit drained state"

==========================

What I am basically trying to do is translate the following into the PCM
playback part of an ALSA driver.

<code>
wHE = HPI_OutStreamGetInfoEx( phSubSys, pOS->hOutStream,
                               &wState, &dwBufferSize,
                              &dwBytesToPlay, &dwSamplesPlayed, NULL);

Data.dwpbData = (HW32)&dataBuffer;

while((dwBytesToPlay<(dwBufferSize-BLOCK_SIZE)))
{
   dwBytesRead=read_some_data(&dataBuffer);
   Data.dwDataSize = dwBytesRead;
   wHE = HPI_OutStreamWrite( phSubSys, pOS->hOutStream, &Data);
   wHE = HPI_OutStreamGetInfo( phSubSys, pOS->hOutStream,
                                &wState, &dwBufferSize, &dwBytesToPlay);

}
</code>

Notes:
wXxxx is 16 bit data, dwXxxx is 32 bit.

wState: STOPPED, PLAYING, DRAINED=ran out of data.
dwBufferSize typically 500K to 1Mbyte
Data is a struct that contains a pointer to data buffer, size of data, and
format info.

Our cards have no interrupts, and no DMA (...yet. The next one probably will) so
they must be polled.

Based on the dummy driver, I am using a timer to do the polling.
So far, it does play audio, but often crashes or locks the machine solid with a
kernel panic.
I need help with the subtleties, and any tips on how to debug this kind of
problem ;-)

 static void snd_card_asihpi_pcm_timer_function(unsigned long data)
 {
 	snd_card_asihpi_pcm_t *dpcm = snd_magic_cast(snd_card_asihpi_pcm_t, (void
*)data, return);
 	snd_pcm_runtime_t *runtime = dpcm->substream->runtime;

 	unsigned int pos;
 	int delta;
 	HW16            wState,err;
 	HW32            dwBufferSize;
 	HW32            dwDataToPlay;
 	HW32            dwSamplesPlayed;

 	dpcm->timer.expires = 1 + jiffies;
 	add_timer(&dpcm->timer);
 	spin_lock_irq(&dpcm->lock);

 	err= HPI_OutStreamGetInfoEx(phSubSys,dpcm->hStream,
 				    &wState,
 				    &dwBufferSize,
 				    &dwDataToPlay,
 				    &dwSamplesPlayed,
 				    NULL);
 	HPI_HandleError( err );
 	//	if ((wState== HPI_STATE_DRAINED))
 	//    snd_pcm_stop(dpcm->substream, SNDRV_PCM_STATE_SETUP);

 	pos  =  frames_to_bytes(runtime, dwSamplesPlayed);
 	pos %= dpcm->pcm_size;
 	delta = pos - dpcm->pcm_buf_pos;
 	dpcm->pcm_buf_pos = pos;
  	if (delta < 0) delta +=  dpcm->pcm_size;

  	dpcm->pcm_irq_pos += delta;

 	if (dpcm->pcm_irq_pos >= dpcm->pcm_count) {
 		dpcm->pcm_irq_pos %= dpcm->pcm_count;
 		snd_pcm_period_elapsed(dpcm->substream);
 	}

 	spin_unlock_irq(&dpcm->lock);
 }

static snd_pcm_uframes_t snd_card_asihpi_playback_pointer(snd_pcm_substream_t *
substream)
{
	snd_pcm_runtime_t *runtime = substream->runtime;
	snd_card_asihpi_pcm_t *dpcm = snd_magic_cast(snd_card_asihpi_pcm_t,
runtime->private_data, return -ENXIO);

    snd_printd(KERN_INFO "playback pointer\n");

	return bytes_to_frames(runtime, dpcm->pcm_buf_pos);
}


static int snd_card_asihpi_playback_copy(
					 snd_pcm_substream_t *substream, int channel,
					 snd_pcm_uframes_t pos,
					 void *src,
					 snd_pcm_uframes_t count)
{
    snd_pcm_runtime_t *runtime = substream->runtime;
    snd_card_asihpi_pcm_t *dpcm = snd_magic_cast(snd_card_asihpi_pcm_t,
runtime->private_data, return -ENXIO);
    HW16 err;
    unsigned int len;

    len = frames_to_bytes(runtime, count);

    if (copy_from_user(runtime->dma_area, src, len))
		return -EFAULT;

    dpcm->Data.dwDataSize = len;
    dpcm->Data.dwpbData = (HW32)runtime->dma_area;

    err = HPI_OutStreamWrite(phSubSys,dpcm->hStream,&dpcm->Data);
    return 0;
}


Is this an appropriate way to structure the driver?
If not, then how?

Thanks for wading through...

Eliot Blennerhassett
www.audioscience.com

Eliot Blennerhassett
AudioScience Inc.
--
Junk footer beyond this point. Read at your own risk.


-------------------------------------------------------------
Sign up for ICQmail at http://www.icq.com/icqmail/signup.html


-------------------------------------------------------
This SF.net email is sponsored by: If flattening out C++ or Java
code to make your application fit in a relational database is painful, 
don't do it! Check out ObjectStore. Now part of Progress Software.
http://www.objectstore.net/sourceforge

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-05-20  9:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-19  9:40 Help needed. (long) Eliot Blennerhassett
2003-05-19 16:10 ` PCI problem Giuliano Pochini
2003-05-20  9:01   ` Takashi Iwai
2003-05-19 16:34 ` Help needed. (long) Takashi Iwai
2003-05-20  8:56   ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.