Re: USB sound card driver - Line6 Toneport UX1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Stefano D'Angelo wrote:
>    urb->transfer_dma = runtime->dma_addr;

This will always play the data at the beginning of the buffer.

fixed

>    urb->transfer_buffer = usb_buffer_alloc (urb->dev,
> LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2, GFP_KERNEL, &urb->transfer_dma);

This buffer should be allocated when the URB is allocated.

fixed

>    memcpy (urb->transfer_buffer, runtime->dma_area + chip->playback_pos *
> 2, LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2);

I hope the buffer size is a multiple of PACKET_SIZE_OUT * 2.

it is

>    urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;

Why the NO_TRANSFER_DMA_MAP?  You shouldn't need to do such
optimizations in the first version of the driver.

ok

>    snd_pcm_period_elapsed (substream);

What is the period size?

period size is 96 = LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2 (double buffering) / 2 (16 bit data), so everytime an urb is sent a period is elapsed.

Here is how I'm doing right now but I still got the same beep for everything I play (when I used the copy () callback it kind of worked, is perphaps possible that the soundcard doesn't support dma transfers?):


static void snd_line6_tp_ux1_complete_playback_transfer (struct urb* urb,
                                                         struct pt_regs* regs)
{
    snd_pcm_substream_t *substream = (snd_pcm_substream_t *)(urb->context);
    struct snd_line6_tp_ux1 *chip = snd_pcm_substream_chip (substream);
    snd_pcm_runtime_t *runtime = substream->runtime;

    chip->playback_pos += LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2 / 2;
    if (chip->playback_pos == runtime->buffer_size) {
        chip->playback_pos -= runtime->buffer_size;

    }

    memcpy (urb->transfer_buffer, runtime->dma_area + chip->playback_pos * 2, LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2);

    snd_pcm_period_elapsed (substream);

    usb_submit_urb (urb, GFP_ATOMIC);
}

static int snd_line6_tp_ux1_pcm_trigger (snd_pcm_substream_t *substream,
                                         int cmd)

{
    struct snd_line6_tp_ux1 *chip = snd_pcm_substream_chip (substream);
    snd_pcm_runtime_t *runtime = substream->runtime;
    static struct urb* urb;

    switch (cmd) {
    case SNDRV_PCM_TRIGGER_START:
        urb = usb_alloc_urb (2, GFP_ATOMIC);
        urb->dev = chip->dev;
        urb->pipe = usb_sndisocpipe (urb->dev, 1);
        urb->complete = snd_line6_tp_ux1_complete_playback_transfer;
        urb->context = substream;

        urb->transfer_dma = runtime->dma_addr;
        urb->transfer_buffer = usb_buffer_alloc (urb->dev,
                 LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2, GFP_ATOMIC,
                 &urb->transfer_dma);
        memcpy (urb->transfer_buffer, runtime->dma_area,
                            LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2);

        urb->transfer_flags = URB_ISO_ASAP; // | URB_NO_TRANSFER_DMA_MAP;
        urb->interval = 1;
        urb->number_of_packets = 2;
        urb->iso_frame_desc[0].offset = 0;
        urb->iso_frame_desc[0].length = urb->iso_frame_desc[1].offset =
        urb->iso_frame_desc[1].length =
                                 LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT;
        chip->playback_pos = 0;
        usb_submit_urb (urb, GFP_KERNEL);
            break;
    case SNDRV_PCM_TRIGGER_STOP:
        usb_buffer_free (chip->dev,

                         LINE6_TP_UX1_48000_16_PACKET_SIZE_OUT * 2,
                         urb->transfer_buffer, urb->transfer_dma);
        usb_free_urb (urb);
            break;
    default:
            return -EINVAL;
        break;
    }

    return 0;
}

Thanks,
Stefano
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux