All of lore.kernel.org
 help / color / mirror / Atom feed
* 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.