* Line6 TonePort
@ 2006-08-10 16:19 Stefano D'Angelo
2006-08-10 16:32 ` Markus Rechberger
2006-08-11 17:21 ` Clemens Ladisch
0 siblings, 2 replies; 9+ messages in thread
From: Stefano D'Angelo @ 2006-08-10 16:19 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1.1: Type: text/plain, Size: 685 bytes --]
I hope this is the last time I write but I don't think so.
The problem is quite simple: this USB card does not support DMA transfers
(yes, seems impossible but that's what it is), so a support for this sound
card is difficult to obtain working on the snd-usb-audio module, Takashi
told me to use an intermediate buffer, but I really don't know how to do it.
Should I copy data from the buffer (playback) on usb transfer completition
callbacks? But in such case isn't it the same to just copy data into the
urb's transfer buffer?
I tried to avoid using this buffer and what I obtain is something that
resembles what the card should be playing but with huge noise.
Please help!
Stefano
[-- Attachment #1.2: Type: text/html, Size: 709 bytes --]
[-- Attachment #2: Type: text/plain, Size: 373 bytes --]
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
[-- Attachment #3: Type: text/plain, Size: 161 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-10 16:19 Line6 TonePort Stefano D'Angelo
@ 2006-08-10 16:32 ` Markus Rechberger
2006-08-10 16:39 ` Stefano D'Angelo
2006-08-11 17:21 ` Clemens Ladisch
1 sibling, 1 reply; 9+ messages in thread
From: Markus Rechberger @ 2006-08-10 16:32 UTC (permalink / raw)
To: Stefano D'Angelo; +Cc: alsa-devel
do you reverse engineer that driver, or do you have any specs?
Markus
On 8/10/06, Stefano D'Angelo <zanga.mail@gmail.com> wrote:
> I hope this is the last time I write but I don't think so.
> The problem is quite simple: this USB card does not support DMA transfers
> (yes, seems impossible but that's what it is), so a support for this sound
> card is difficult to obtain working on the snd-usb-audio module, Takashi
> told me to use an intermediate buffer, but I really don't know how to do it.
> Should I copy data from the buffer (playback) on usb transfer completition
> callbacks? But in such case isn't it the same to just copy data into the
> urb's transfer buffer?
> I tried to avoid using this buffer and what I obtain is something that
> resembles what the card should be playing but with huge noise.
> Please help!
>
> Stefano
>
>
--
Markus Rechberger
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-10 16:32 ` Markus Rechberger
@ 2006-08-10 16:39 ` Stefano D'Angelo
0 siblings, 0 replies; 9+ messages in thread
From: Stefano D'Angelo @ 2006-08-10 16:39 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1.1: Type: text/plain, Size: 1123 bytes --]
reverse engineer... but i managed to have it playing good. the problem is
that i used the copy callback and so mmaping was not avaible
Stefano
2006/8/10, Markus Rechberger <mrechberger@gmail.com>:
>
> do you reverse engineer that driver, or do you have any specs?
>
> Markus
>
> On 8/10/06, Stefano D'Angelo <zanga.mail@gmail.com> wrote:
> > I hope this is the last time I write but I don't think so.
> > The problem is quite simple: this USB card does not support DMA
> transfers
> > (yes, seems impossible but that's what it is), so a support for this
> sound
> > card is difficult to obtain working on the snd-usb-audio module, Takashi
> > told me to use an intermediate buffer, but I really don't know how to do
> it.
> > Should I copy data from the buffer (playback) on usb transfer
> completition
> > callbacks? But in such case isn't it the same to just copy data into the
> > urb's transfer buffer?
> > I tried to avoid using this buffer and what I obtain is something that
> > resembles what the card should be playing but with huge noise.
> > Please help!
> >
> > Stefano
> >
> >
>
>
> --
> Markus Rechberger
>
[-- Attachment #1.2: Type: text/html, Size: 1488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 373 bytes --]
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
[-- Attachment #3: Type: text/plain, Size: 161 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-10 16:19 Line6 TonePort Stefano D'Angelo
2006-08-10 16:32 ` Markus Rechberger
@ 2006-08-11 17:21 ` Clemens Ladisch
2006-08-11 20:07 ` Stefano D'Angelo
1 sibling, 1 reply; 9+ messages in thread
From: Clemens Ladisch @ 2006-08-11 17:21 UTC (permalink / raw)
To: Stefano D'Angelo, alsa-devel
Stefano D'Angelo wrote:
> The problem is quite simple: this USB card does not support DMA transfers
No USB device supports DMA transfers. USB devices support USB transfers.
The host controller supports DMA transfers. Yours does, too.
> Takashi told me to use an intermediate buffer,
This is just because the buffer for a USB frame must be continguous, but
you cannot always guarantee this when you're near the end of ALSA's ring
buffer.
> but I really don't know how to do it. Should I copy data from the
> buffer (playback) on usb transfer completition callbacks?
You should copy the data just before you submit the URB. In other words,
yes.
> But in such case isn't it the same to just copy data into the urb's
> transfer buffer?
This is indeed the same. The URB's transfer buffer _is_ the
intermediate buffer mentioned by Takashi.
The opposite, i.e., not using an intermediate buffer, would mean that
the URB's transfer_buffer pointed into ALSA's ring buffer.
> I tried to avoid using this buffer and what I obtain is something that
> resembles what the card should be playing but with huge noise.
How do you determine how much data to send in each USB frame?
Regards,
Clemens
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-11 17:21 ` Clemens Ladisch
@ 2006-08-11 20:07 ` Stefano D'Angelo
2006-08-11 23:44 ` Markus Rechberger
0 siblings, 1 reply; 9+ messages in thread
From: Stefano D'Angelo @ 2006-08-11 20:07 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1.1: Type: text/plain, Size: 1062 bytes --]
Markus: I use USB Snoopy Pro and I'm sure that packet sizes are ok, I'm just
trying to do as the Windows' driver does.
Clemens:
> No USB device supports DMA transfers. USB devices support USB transfers.
> The host controller supports DMA transfers. Yours does, too.
Well, I thought so. But I even modified snd-usb-audio driver (quirks + other
code) to support this card and what I get out of it is the same thing I got
when I tried with DMA on my own: a kind of buzz sound that sometimes
continues after stopping the playback.
As you can see from the code I posted I'm not going this way, I'm copying
the data from runtime->dma_area into the URB transfer_buffer I allocate.
> You should copy the data just before you submit the URB. In other words,
> yes.
I copy and send in the same function, is it right?
> How do you determine how much data to send in each USB frame?
I use fixed sizes (as the windows' driver do). In snd_toneport.h each size
is specified according to the different altsettings. Each URB has 2 isoch.
packets of the same size.
Stefano
[-- Attachment #1.2: Type: text/html, Size: 1152 bytes --]
[-- Attachment #2: Type: text/plain, Size: 373 bytes --]
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
[-- Attachment #3: Type: text/plain, Size: 161 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-11 20:07 ` Stefano D'Angelo
@ 2006-08-11 23:44 ` Markus Rechberger
2006-08-14 8:46 ` Stefano D'Angelo
0 siblings, 1 reply; 9+ messages in thread
From: Markus Rechberger @ 2006-08-11 23:44 UTC (permalink / raw)
To: Stefano D'Angelo; +Cc: alsa-devel
Hi,
try to replay packets with a constant value like zero, you shouldn't
hear any noise then, try to vary with the packet size, and maybe use
USBSnoop for determining that (at least I was able to clearly
determine what's going on..) I have no serious experience with other
USB sniffers, I just used others but the outputs weren't as easy
readable as with USBSnoop.
Somehow I think we exactly have the same problem (but I almost solved my one..)
Do all packets have the same packetsize? My USB Device varies with that too..
After exactly 46 seconds I get some buzz too with my device at the
moment :( I couldn't determine any sync stuff there yet.. though I
haven't correctly implemented the record feature correctly yet which
might affect the other part as well .. let's see..
On 8/11/06, Stefano D'Angelo <zanga.mail@gmail.com> wrote:
> Markus: I use USB Snoopy Pro and I'm sure that packet sizes are ok, I'm just
> trying to do as the Windows' driver does.
>
> Clemens:
> > No USB device supports DMA transfers. USB devices support USB transfers.
> > The host controller supports DMA transfers. Yours does, too.
I thought so too it sound kinda strange...
> Well, I thought so. But I even modified snd-usb-audio driver (quirks + other
> code) to support this card and what I get out of it is the same thing I got
> when I tried with DMA on my own: a kind of buzz sound that sometimes
> continues after stopping the playback.
wrong device setup.
> As you can see from the code I posted I'm not going this way, I'm copying
> the data from runtime->dma_area into the URB transfer_buffer I allocate.
>
you have to do this anyway?! runtime->dma_area is alsa specific, and
transfer_buffer is USB specific
> > You should copy the data just before you submit the URB. In other words,
> > yes.
> I copy and send in the same function, is it right?
>
> > How do you determine how much data to send in each USB frame?
> I use fixed sizes (as the windows' driver do). In snd_toneport.h each size
> is specified according to the different altsettings. Each URB has 2 isoch.
> packets of the same size.
could you also provide a 20 MB USBSnoop (not usb snoopy) logfile
(please zip it somewhere)
cheers,
Markus
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-11 23:44 ` Markus Rechberger
@ 2006-08-14 8:46 ` Stefano D'Angelo
2006-08-14 15:22 ` Markus Rechberger
0 siblings, 1 reply; 9+ messages in thread
From: Stefano D'Angelo @ 2006-08-14 8:46 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1.1: Type: text/plain, Size: 6729 bytes --]
Clemens you were right of course, what I was saying was just bull shit (and
I'm sorry).
However the problem remains... I really don't know what's wrong with my code
so I post the "interesting parts" here. Please help, I DO need this card to
work!
static snd_pcm_hardware_t snd_toneport_playback_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_3LE,
.rates = SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000,
.rate_min = 44100,
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2,
.period_bytes_min = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
.period_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
.periods_min = 1,
.periods_max = 2
};
Here period_bytes_min are is as the maximum period size to use just one PCM.
#define snd_toneport_period_elapsed(old, new) \
(new >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2) || \
((old < TONEPORT_48000_24_PACKET_SIZE_OUT * 2) && \
(new >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2))
This one should test if a period is elapsed based on the old playback
position (I see other drivers call such pointers hwptr) and the new one
(before this last is "normalized").
/*
* null urb trasfer's completition callback
*/
static void snd_toneport_playback_complete_first(struct urb* urb,
struct pt_regs* regs)
{
snd_pcm_substream_t *substream = (snd_pcm_substream_t *)(urb->context);
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_toneport *chip = snd_pcm_substream_chip(substream);
memcpy(urb->transfer_buffer, runtime->dma_area,
chip->playback_packet_size * 2);
urb->complete = snd_toneport_playback_complete;
usb_submit_urb(urb, GFP_ATOMIC);
}
/*
* playback transfers' completition callback
*/
static void snd_toneport_playback_complete(struct urb* urb,
struct pt_regs* regs)
{
snd_pcm_substream_t *substream = (snd_pcm_substream_t *)(urb->context);
snd_pcm_runtime_t *runtime = substream->runtime;
struct snd_toneport *chip = snd_pcm_substream_chip(substream);
int new_pos = chip->playback_pos + chip->playback_packet_size * 2;
int offs;
if (new_pos <= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2) {
memcpy(urb->transfer_buffer,
runtime->dma_area + chip->playback_pos,
chip->playback_packet_size * 2);
} else {
offs = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2 -
chip->playback_pos;
memcpy(urb->transfer_buffer,
runtime->dma_area + chip->playback_pos,
offs);
memcpy(urb->transfer_buffer + new_pos,
runtime->dma_area,
chip->playback_packet_size * 2 - offs);
}
if (snd_toneport_period_elapsed(chip->playback_pos, new_pos)) {
if (new_pos >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2)
new_pos -= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2;
chip->playback_pos = new_pos;
snd_pcm_period_elapsed(substream);
} else {
chip->playback_pos = new_pos;
}
if (chip->status & TONEPORT_STATUS_PLAYBACK)
usb_submit_urb(urb, GFP_ATOMIC);
}
/*
* hw_params callback
*
* TODO: capture and full duplex
*/
static int snd_toneport_pcm_hw_params(snd_pcm_substream_t *substream,
snd_pcm_hw_params_t *hw_params)
{
struct snd_toneport *chip = snd_pcm_substream_chip(substream);
unsigned char msg[] = TONEPORT_MSG_3;
int alt, err;
alt = (params_format(hw_params) == SNDRV_PCM_FORMAT_S16_LE) ? 1 : 3;
if ((params_rate(hw_params) == 44100))
alt++;
if ((err = usb_set_interface(chip->dev, 0, alt)) < 0)
return err;
chip->altsetting = alt;
if ((err = snd_toneport_submit_control_transfer(chip->dev, msg)) < 0)
return err;
chip->playback_packet_size = out_sizes[alt - 1];
if (!chip->playback_urb) {
chip->playback_urb = usb_alloc_urb(2, GFP_KERNEL);
chip->playback_urb->dev = chip->dev;
chip->playback_urb->pipe = usb_sndisocpipe(chip->dev, 1);
chip->playback_urb->context = substream;
chip->playback_urb->transfer_flags = URB_ISO_ASAP |
URB_NO_TRANSFER_DMA_MAP;
chip->playback_urb->interval = 1;
chip->playback_urb->number_of_packets = 2;
chip->playback_urb->iso_frame_desc[0].offset = 0;
} else {
usb_buffer_free(chip->dev, chip->playback_packet_size * 2,
chip->playback_urb->transfer_buffer,
chip->playback_urb->transfer_dma);
}
if (!(chip->playback_urb->transfer_buffer =
usb_buffer_alloc(chip->dev, chip->playback_packet_size * 2,
GFP_KERNEL, &chip->playback_urb->transfer_dma)))
return -ENOMEM;
chip->playback_urb->transfer_buffer_length =
chip->playback_packet_size * 2;
chip->playback_urb->iso_frame_desc[0].length =
chip->playback_urb->iso_frame_desc[1].offset =
chip->playback_urb->iso_frame_desc[1].length =
chip->playback_packet_size;
return snd_pcm_lib_malloc_pages(substream,
TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2);
}
/*
* trigger callback
*/
static int snd_toneport_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
{
struct snd_toneport *chip = snd_pcm_substream_chip(substream);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
memset(chip->playback_urb->transfer_buffer, 0,
chip->playback_packet_size * 2);
chip->playback_pos = 0;
chip->status |= TONEPORT_STATUS_PLAYBACK;
chip->playback_urb->complete =
snd_toneport_playback_complete_first;
return usb_submit_urb(chip->playback_urb, GFP_ATOMIC);
break;
case SNDRV_PCM_TRIGGER_STOP:
chip->status &= ~TONEPORT_STATUS_PLAYBACK;
break;
default:
return -EINVAL;
break;
}
return 0;
}
/*
* pointer callback
*/
static snd_pcm_uframes_t snd_toneport_pcm_pointer(
snd_pcm_substream_t* substream)
{
struct snd_toneport *chip = snd_pcm_substream_chip(substream);
return bytes_to_frames(substream->runtime, chip->playback_pos);
}
As you can see I chose to store the playback position in bytes instead of
frames because I have 6-bytes frames and 4-bytes frames (depends on the
format).
Also TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2 is the alsa buffer size.
Thanks,
Stefano
[-- Attachment #1.2: Type: text/html, Size: 11356 bytes --]
[-- Attachment #2: Type: text/plain, Size: 373 bytes --]
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
[-- Attachment #3: Type: text/plain, Size: 161 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-14 8:46 ` Stefano D'Angelo
@ 2006-08-14 15:22 ` Markus Rechberger
2006-08-16 20:46 ` Stefano D'Angelo
0 siblings, 1 reply; 9+ messages in thread
From: Markus Rechberger @ 2006-08-14 15:22 UTC (permalink / raw)
To: Stefano D'Angelo; +Cc: alsa-devel
Hi,
.buffer_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2,
.period_bytes_min = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
.period_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
I don't know what value TONEPORT_48000_24_PACKET_SIZE_OUT is _BUT_
I had to take care about this in my driver too.
The max packet size is 128 bytes, but I'm only allowed to fill 18-20 bytes.
Theoretically I could submit 2560 bytes within one urb but as soon as
I submit more than 384 bytes or less I get a buzz or choppy sound.
Have a look at the windows usbsnoop logs again.
Here's the code of my usb audio driver:
http://kurzlink.de/sBMLkXGXe
Markus
On 8/14/06, Stefano D'Angelo <zanga.mail@gmail.com> wrote:
> Clemens you were right of course, what I was saying was just bull shit (and
> I'm sorry).
> However the problem remains... I really don't know what's wrong with my code
> so I post the "interesting parts" here. Please help, I DO need this card to
> work!
>
> static snd_pcm_hardware_t snd_toneport_playback_hw = {
> .info = SNDRV_PCM_INFO_MMAP |
> SNDRV_PCM_INFO_INTERLEAVED |
> SNDRV_PCM_INFO_BLOCK_TRANSFER |
> SNDRV_PCM_INFO_MMAP_VALID,
> .formats = SNDRV_PCM_FMTBIT_S16_LE |
> SNDRV_PCM_FMTBIT_S24_3LE,
> .rates = SNDRV_PCM_RATE_44100 |
> SNDRV_PCM_RATE_48000,
> .rate_min = 44100,
> .rate_max = 48000,
> .channels_min = 2,
> .channels_max = 2,
> .buffer_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2,
> .period_bytes_min = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
> .period_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
> .periods_min = 1,
> .periods_max = 2
> };
>
> Here period_bytes_min are is as the maximum period size to use just one PCM.
>
> #define snd_toneport_period_elapsed(old, new) \
> (new >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2) || \
> ((old < TONEPORT_48000_24_PACKET_SIZE_OUT * 2) && \
> (new >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2))
>
> This one should test if a period is elapsed based on the old playback
> position (I see other drivers call such pointers hwptr) and the new one
> (before this last is "normalized").
>
> /*
> * null urb trasfer's completition callback
> */
> static void snd_toneport_playback_complete_first(struct urb* urb,
> struct pt_regs* regs)
> {
> snd_pcm_substream_t *substream = (snd_pcm_substream_t *)(urb->context);
> snd_pcm_runtime_t *runtime = substream->runtime;
> struct snd_toneport *chip = snd_pcm_substream_chip(substream);
>
> memcpy(urb->transfer_buffer, runtime->dma_area,
> chip->playback_packet_size * 2);
>
> urb->complete = snd_toneport_playback_complete;
>
> usb_submit_urb(urb, GFP_ATOMIC);
> }
>
> /*
> * playback transfers' completition callback
> */
> static void snd_toneport_playback_complete(struct urb* urb,
> struct pt_regs* regs)
> {
> snd_pcm_substream_t *substream = (snd_pcm_substream_t *)(urb->context);
> snd_pcm_runtime_t *runtime = substream->runtime;
> struct snd_toneport *chip = snd_pcm_substream_chip(substream);
> int new_pos = chip->playback_pos + chip->playback_packet_size * 2;
> int offs;
>
> if (new_pos <= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2) {
> memcpy(urb->transfer_buffer,
> runtime->dma_area + chip->playback_pos,
> chip->playback_packet_size * 2);
> } else {
> offs = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2 -
> chip->playback_pos;
> memcpy(urb->transfer_buffer,
> runtime->dma_area + chip->playback_pos,
> offs);
> memcpy(urb->transfer_buffer + new_pos,
> runtime->dma_area,
> chip->playback_packet_size * 2 - offs);
> }
>
> if (snd_toneport_period_elapsed(chip->playback_pos, new_pos)) {
> if (new_pos >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2)
> new_pos -= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2;
> chip->playback_pos = new_pos;
> snd_pcm_period_elapsed(substream);
> } else {
> chip->playback_pos = new_pos;
> }
>
> if (chip->status & TONEPORT_STATUS_PLAYBACK)
> usb_submit_urb(urb, GFP_ATOMIC);
> }
>
> /*
> * hw_params callback
> *
> * TODO: capture and full duplex
> */
> static int snd_toneport_pcm_hw_params(snd_pcm_substream_t *substream,
> snd_pcm_hw_params_t *hw_params)
> {
> struct snd_toneport *chip = snd_pcm_substream_chip(substream);
> unsigned char msg[] = TONEPORT_MSG_3;
> int alt, err;
>
> alt = (params_format(hw_params) == SNDRV_PCM_FORMAT_S16_LE) ? 1 : 3;
> if ((params_rate(hw_params) == 44100))
> alt++;
>
> if ((err = usb_set_interface(chip->dev, 0, alt)) < 0)
> return err;
> chip->altsetting = alt;
>
> if ((err = snd_toneport_submit_control_transfer(chip->dev, msg)) < 0)
> return err;
>
> chip->playback_packet_size = out_sizes[alt - 1];
> if (!chip->playback_urb) {
> chip->playback_urb = usb_alloc_urb(2, GFP_KERNEL);
> chip->playback_urb->dev = chip->dev;
> chip->playback_urb->pipe = usb_sndisocpipe(chip->dev, 1);
> chip->playback_urb->context = substream;
> chip->playback_urb->transfer_flags = URB_ISO_ASAP |
> URB_NO_TRANSFER_DMA_MAP;
> chip->playback_urb->interval = 1;
> chip->playback_urb->number_of_packets = 2;
> chip->playback_urb->iso_frame_desc[0].offset = 0;
> } else {
> usb_buffer_free(chip->dev, chip->playback_packet_size * 2,
> chip->playback_urb->transfer_buffer,
> chip->playback_urb->transfer_dma);
> }
> if (!(chip->playback_urb->transfer_buffer =
> usb_buffer_alloc(chip->dev, chip->playback_packet_size * 2,
> GFP_KERNEL, &chip->playback_urb->transfer_dma)))
> return -ENOMEM;
> chip->playback_urb->transfer_buffer_length =
> chip->playback_packet_size * 2;
> chip->playback_urb->iso_frame_desc[0].length =
> chip->playback_urb->iso_frame_desc[1].offset =
> chip->playback_urb->iso_frame_desc[1].length =
> chip->playback_packet_size;
>
> return snd_pcm_lib_malloc_pages(substream,
> TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2);
> }
>
> /*
> * trigger callback
> */
> static int snd_toneport_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
> {
> struct snd_toneport *chip = snd_pcm_substream_chip(substream);
>
> switch (cmd) {
> case SNDRV_PCM_TRIGGER_START:
> memset(chip->playback_urb->transfer_buffer, 0,
> chip->playback_packet_size * 2);
> chip->playback_pos = 0;
> chip->status |= TONEPORT_STATUS_PLAYBACK;
> chip->playback_urb->complete =
> snd_toneport_playback_complete_first;
> return usb_submit_urb(chip->playback_urb, GFP_ATOMIC);
> break;
> case SNDRV_PCM_TRIGGER_STOP:
> chip->status &= ~TONEPORT_STATUS_PLAYBACK;
> break;
> default:
> return -EINVAL;
> break;
> }
>
> return 0;
> }
>
> /*
> * pointer callback
> */
> static snd_pcm_uframes_t snd_toneport_pcm_pointer(
> snd_pcm_substream_t* substream)
> {
> struct snd_toneport *chip = snd_pcm_substream_chip(substream);
>
> return bytes_to_frames(substream->runtime, chip->playback_pos);
> }
>
> As you can see I chose to store the playback position in bytes instead of
> frames because I have 6-bytes frames and 4-bytes frames (depends on the
> format).
> Also TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2 is the alsa buffer size.
> Thanks,
>
> Stefano
>
>
--
Markus Rechberger
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Line6 TonePort
2006-08-14 15:22 ` Markus Rechberger
@ 2006-08-16 20:46 ` Stefano D'Angelo
0 siblings, 0 replies; 9+ messages in thread
From: Stefano D'Angelo @ 2006-08-16 20:46 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1.1: Type: text/plain, Size: 8529 bytes --]
Ok, but I know it works when you "fill" the endpoint... I had it working but
with playback callback. That way, however, I hadn't got mmap and that's why
now I'm going crazy!
2006/8/14, Markus Rechberger <mrechberger@gmail.com>:
>
> Hi,
>
> .buffer_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2,
> .period_bytes_min = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
> .period_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
>
> I don't know what value TONEPORT_48000_24_PACKET_SIZE_OUT is _BUT_
> I had to take care about this in my driver too.
> The max packet size is 128 bytes, but I'm only allowed to fill 18-20
> bytes.
> Theoretically I could submit 2560 bytes within one urb but as soon as
> I submit more than 384 bytes or less I get a buzz or choppy sound.
> Have a look at the windows usbsnoop logs again.
>
> Here's the code of my usb audio driver:
> http://kurzlink.de/sBMLkXGXe
>
> Markus
>
> On 8/14/06, Stefano D'Angelo <zanga.mail@gmail.com> wrote:
> > Clemens you were right of course, what I was saying was just bull shit
> (and
> > I'm sorry).
> > However the problem remains... I really don't know what's wrong with my
> code
> > so I post the "interesting parts" here. Please help, I DO need this card
> to
> > work!
> >
> > static snd_pcm_hardware_t snd_toneport_playback_hw = {
> > .info = SNDRV_PCM_INFO_MMAP |
> > SNDRV_PCM_INFO_INTERLEAVED |
> > SNDRV_PCM_INFO_BLOCK_TRANSFER |
> > SNDRV_PCM_INFO_MMAP_VALID,
> > .formats = SNDRV_PCM_FMTBIT_S16_LE |
> > SNDRV_PCM_FMTBIT_S24_3LE,
> > .rates = SNDRV_PCM_RATE_44100 |
> > SNDRV_PCM_RATE_48000,
> > .rate_min = 44100,
> > .rate_max = 48000,
> > .channels_min = 2,
> > .channels_max = 2,
> > .buffer_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2,
> > .period_bytes_min = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
> > .period_bytes_max = TONEPORT_48000_24_PACKET_SIZE_OUT * 2,
> > .periods_min = 1,
> > .periods_max = 2
> > };
> >
> > Here period_bytes_min are is as the maximum period size to use just one
> PCM.
> >
> > #define snd_toneport_period_elapsed(old, new) \
> > (new >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2) || \
> > ((old < TONEPORT_48000_24_PACKET_SIZE_OUT * 2) && \
> > (new >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2))
> >
> > This one should test if a period is elapsed based on the old playback
> > position (I see other drivers call such pointers hwptr) and the new one
> > (before this last is "normalized").
> >
> > /*
> > * null urb trasfer's completition callback
> > */
> > static void snd_toneport_playback_complete_first(struct urb* urb,
> > struct pt_regs* regs)
> > {
> > snd_pcm_substream_t *substream = (snd_pcm_substream_t
> *)(urb->context);
> > snd_pcm_runtime_t *runtime = substream->runtime;
> > struct snd_toneport *chip = snd_pcm_substream_chip(substream);
> >
> > memcpy(urb->transfer_buffer, runtime->dma_area,
> > chip->playback_packet_size * 2);
> >
> > urb->complete = snd_toneport_playback_complete;
> >
> > usb_submit_urb(urb, GFP_ATOMIC);
> > }
> >
> > /*
> > * playback transfers' completition callback
> > */
> > static void snd_toneport_playback_complete(struct urb* urb,
> > struct pt_regs* regs)
> > {
> > snd_pcm_substream_t *substream = (snd_pcm_substream_t
> *)(urb->context);
> > snd_pcm_runtime_t *runtime = substream->runtime;
> > struct snd_toneport *chip = snd_pcm_substream_chip(substream);
> > int new_pos = chip->playback_pos + chip->playback_packet_size * 2;
> > int offs;
> >
> > if (new_pos <= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2) {
> > memcpy(urb->transfer_buffer,
> > runtime->dma_area + chip->playback_pos,
> > chip->playback_packet_size * 2);
> > } else {
> > offs = TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2 -
> > chip->playback_pos;
> > memcpy(urb->transfer_buffer,
> > runtime->dma_area + chip->playback_pos,
> > offs);
> > memcpy(urb->transfer_buffer + new_pos,
> > runtime->dma_area,
> > chip->playback_packet_size * 2 - offs);
> > }
> >
> > if (snd_toneport_period_elapsed(chip->playback_pos, new_pos)) {
> > if (new_pos >= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2)
> > new_pos -= TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2;
> > chip->playback_pos = new_pos;
> > snd_pcm_period_elapsed(substream);
> > } else {
> > chip->playback_pos = new_pos;
> > }
> >
> > if (chip->status & TONEPORT_STATUS_PLAYBACK)
> > usb_submit_urb(urb, GFP_ATOMIC);
> > }
> >
> > /*
> > * hw_params callback
> > *
> > * TODO: capture and full duplex
> > */
> > static int snd_toneport_pcm_hw_params(snd_pcm_substream_t *substream,
> > snd_pcm_hw_params_t *hw_params)
> > {
> > struct snd_toneport *chip = snd_pcm_substream_chip(substream);
> > unsigned char msg[] = TONEPORT_MSG_3;
> > int alt, err;
> >
> > alt = (params_format(hw_params) == SNDRV_PCM_FORMAT_S16_LE) ? 1 : 3;
> > if ((params_rate(hw_params) == 44100))
> > alt++;
> >
> > if ((err = usb_set_interface(chip->dev, 0, alt)) < 0)
> > return err;
> > chip->altsetting = alt;
> >
> > if ((err = snd_toneport_submit_control_transfer(chip->dev, msg)) <
> 0)
> > return err;
> >
> > chip->playback_packet_size = out_sizes[alt - 1];
> > if (!chip->playback_urb) {
> > chip->playback_urb = usb_alloc_urb(2, GFP_KERNEL);
> > chip->playback_urb->dev = chip->dev;
> > chip->playback_urb->pipe = usb_sndisocpipe(chip->dev, 1);
> > chip->playback_urb->context = substream;
> > chip->playback_urb->transfer_flags = URB_ISO_ASAP |
> > URB_NO_TRANSFER_DMA_MAP;
> > chip->playback_urb->interval = 1;
> > chip->playback_urb->number_of_packets = 2;
> > chip->playback_urb->iso_frame_desc[0].offset = 0;
> > } else {
> > usb_buffer_free(chip->dev, chip->playback_packet_size * 2,
> > chip->playback_urb->transfer_buffer,
> > chip->playback_urb->transfer_dma);
> > }
> > if (!(chip->playback_urb->transfer_buffer =
> > usb_buffer_alloc(chip->dev, chip->playback_packet_size * 2,
> > GFP_KERNEL, &chip->playback_urb->transfer_dma)))
> > return -ENOMEM;
> > chip->playback_urb->transfer_buffer_length =
> > chip->playback_packet_size * 2;
> > chip->playback_urb->iso_frame_desc[0].length =
> > chip->playback_urb->iso_frame_desc[1].offset =
> > chip->playback_urb->iso_frame_desc[1].length =
> > chip->playback_packet_size;
> >
> > return snd_pcm_lib_malloc_pages(substream,
> > TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2);
> > }
> >
> > /*
> > * trigger callback
> > */
> > static int snd_toneport_pcm_trigger(snd_pcm_substream_t *substream, int
> cmd)
> > {
> > struct snd_toneport *chip = snd_pcm_substream_chip(substream);
> >
> > switch (cmd) {
> > case SNDRV_PCM_TRIGGER_START:
> > memset(chip->playback_urb->transfer_buffer, 0,
> > chip->playback_packet_size * 2);
> > chip->playback_pos = 0;
> > chip->status |= TONEPORT_STATUS_PLAYBACK;
> > chip->playback_urb->complete =
> > snd_toneport_playback_complete_first;
> > return usb_submit_urb(chip->playback_urb, GFP_ATOMIC);
> > break;
> > case SNDRV_PCM_TRIGGER_STOP:
> > chip->status &= ~TONEPORT_STATUS_PLAYBACK;
> > break;
> > default:
> > return -EINVAL;
> > break;
> > }
> >
> > return 0;
> > }
> >
> > /*
> > * pointer callback
> > */
> > static snd_pcm_uframes_t snd_toneport_pcm_pointer(
> > snd_pcm_substream_t* substream)
> > {
> > struct snd_toneport *chip = snd_pcm_substream_chip(substream);
> >
> > return bytes_to_frames(substream->runtime, chip->playback_pos);
> > }
> >
> > As you can see I chose to store the playback position in bytes instead
> of
> > frames because I have 6-bytes frames and 4-bytes frames (depends on the
> > format).
> > Also TONEPORT_48000_24_PACKET_SIZE_OUT * 2 * 2 is the alsa buffer size.
> > Thanks,
> >
> > Stefano
> >
> >
>
>
> --
> Markus Rechberger
>
[-- Attachment #1.2: Type: text/html, Size: 15130 bytes --]
[-- Attachment #2: Type: text/plain, Size: 373 bytes --]
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
[-- Attachment #3: Type: text/plain, Size: 161 bytes --]
_______________________________________________
Alsa-devel mailing list
Alsa-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/alsa-devel
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-08-16 20:46 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-10 16:19 Line6 TonePort Stefano D'Angelo
2006-08-10 16:32 ` Markus Rechberger
2006-08-10 16:39 ` Stefano D'Angelo
2006-08-11 17:21 ` Clemens Ladisch
2006-08-11 20:07 ` Stefano D'Angelo
2006-08-11 23:44 ` Markus Rechberger
2006-08-14 8:46 ` Stefano D'Angelo
2006-08-14 15:22 ` Markus Rechberger
2006-08-16 20:46 ` Stefano D'Angelo
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.