Changeset dce7e41 in mainline


Ignore:
Timestamp:
2011-10-21T21:59:30Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
962ef67
Parents:
f14e6ea
Message:

sb16: Implement playback.

Use 16bit dma transfers for now.

Location:
uspace/drv/audio/sb16
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/sb16/dsp.c

    rf14e6ea rdce7e41  
    4343
    4444#define BUFFER_SIZE (PAGE_SIZE / 4)
     45#define PLAY_BLOCK_SIZE (BUFFER_SIZE / 2)
    4546
    4647#ifndef DSP_RETRY_COUNT
     
    110111        const int ret = dma_setup_channel(SB_DMA_CHAN_16, pa, BUFFER_SIZE);
    111112        if (ret == EOK) {
    112                 dsp->buffer.buffer_data = buffer;
    113                 dsp->buffer.buffer_position = buffer;
    114                 dsp->buffer.buffer_size = BUFFER_SIZE;
     113                dsp->buffer.data = buffer;
     114                dsp->buffer.position = buffer;
     115                dsp->buffer.size = BUFFER_SIZE;
     116                memset(buffer, 0x8f, BUFFER_SIZE);
    115117                dma_prepare_channel(SB_DMA_CHAN_16, false, true, BLOCK_DMA);
    116118                /* Set 8bit channel */
     
    130132static inline void sb_clear_buffer(sb_dsp_t *dsp)
    131133{
    132         free24(dsp->buffer.buffer_data);
    133         dsp->buffer.buffer_data = NULL;
    134         dsp->buffer.buffer_position = NULL;
    135         dsp->buffer.buffer_size = 0;
     134        free24(dsp->buffer.data);
     135        dsp->buffer.data = NULL;
     136        dsp->buffer.position = NULL;
     137        dsp->buffer.size = 0;
    136138}
    137139/*----------------------------------------------------------------------------*/
     
    172174        /* ACK dma8 transfer interrupt */
    173175        pio_read_8(&dsp->regs->dsp_read_status);
     176
     177        static size_t interrupt_count = 0;
     178
     179        const size_t remain_size = dsp->playing.size -
     180            (dsp->playing.position - dsp->playing.data);
     181
     182        ddf_log_note("Interrupt count %zu, remaining: %zu.\n",
     183            ++interrupt_count, remain_size);
     184        if (remain_size == 0) {
     185                ddf_log_note("Nothing more to play");
     186                sb_dsp_write(dsp, DMA_16B_EXIT);
     187                sb_clear_buffer(dsp);
     188                return;
     189        }
     190        if (remain_size < PLAY_BLOCK_SIZE) {
     191                ddf_log_note("Last %zu bytes to play.\n", remain_size);
     192                /* This is the last block */
     193                memcpy(dsp->buffer.position, dsp->playing.position, remain_size);
     194                dsp->playing.position += remain_size;
     195                dsp->buffer.position += remain_size;
     196                sb_dsp_write(dsp, SINGLE_DMA_16B_DA);
     197                sb_dsp_write(dsp, dsp->playing.mode);
     198                sb_dsp_write(dsp, remain_size & 0xff);
     199                sb_dsp_write(dsp, remain_size >> 8);
     200                return;
     201        }
     202        ddf_log_note("Playing full block.\n");
     203        memcpy(dsp->buffer.position, dsp->playing.position, PLAY_BLOCK_SIZE);
     204        dsp->playing.position += PLAY_BLOCK_SIZE;
     205        dsp->buffer.position += PLAY_BLOCK_SIZE;
     206        /* Wrap around */
     207        if (dsp->buffer.position == (dsp->buffer.data + dsp->buffer.size))
     208                dsp->buffer.position = dsp->buffer.data;
     209
    174210}
    175211/*----------------------------------------------------------------------------*/
     
    203239                return ENOTSUP;
    204240
     241        ddf_log_fatal("Buffer prepare.\n");
    205242        const int ret = sb_setup_buffer(dsp);
    206 
    207         return ret;
     243        if (ret != EOK)
     244                return ret;
     245
     246        const size_t play_size =
     247            size < PLAY_BLOCK_SIZE ? size : PLAY_BLOCK_SIZE;
     248        memcpy(dsp->buffer.data, dsp->playing.data, play_size);
     249
     250        ddf_log_note("Playing sound: %zu(%zu) bytes.\n", play_size, size);
     251
     252        dsp->playing.data = data;
     253        dsp->playing.position = data + play_size;
     254        dsp->playing.size = size;
     255        dsp->playing.mode =
     256            (bit_depth == 16 ? 0x10 : 0) | (channels == 2 ? 0x20 : 0);
     257
     258        sb_dsp_write(dsp, SET_SAMPLING_RATE_OUTPUT);
     259        sb_dsp_write(dsp, sampling_rate >> 8);
     260        sb_dsp_write(dsp, sampling_rate & 0xff);
     261
     262        sb_dsp_write(dsp, AUTO_DMA_16B_DA_FIFO);
     263        sb_dsp_write(dsp, dsp->playing.mode);
     264        sb_dsp_write(dsp, play_size & 0xff);
     265        sb_dsp_write(dsp, play_size >> 8);
     266
     267        return EOK;
    208268}
    209269/**
  • uspace/drv/audio/sb16/dsp.h

    rf14e6ea rdce7e41  
    4747        } version;
    4848        struct {
    49                 uint8_t *buffer_data;
    50                 uint8_t *buffer_position;
    51                 size_t buffer_size;
     49                uint8_t *data;
     50                uint8_t *position;
     51                size_t size;
    5252        } buffer;
     53        struct {
     54                const uint8_t *data;
     55                const uint8_t *position;
     56                size_t size;
     57                uint8_t mode;
     58        } playing;
    5359} sb_dsp_t;
    5460
  • uspace/drv/audio/sb16/sb16.c

    rf14e6ea rdce7e41  
    103103{
    104104        assert(drv);
    105         ddf_log_note("SB16 interrupt.\n");
    106105        /* The acknowledgment of interrupts on DSP version 4.xx is different;
    107106         * It can contain MPU-401 indicator and DMA16 transfers are acked
     
    110109                pio_write_8(&drv->regs->mixer_address, MIXER_IRQ_ADDRESS);
    111110                const uint8_t irq_mask = pio_read_8(&drv->regs->mixer_data);
    112                 ddf_log_note("SB16 IRQ mask %hhx.\n", irq_mask);
     111                ddf_log_debug("SB16 IRQ mask %hhx.\n", irq_mask);
    113112                /* Third bit is MPU-401 interrupt */
    114113                if (irq_mask & 0x4) {
    115114                        return;
    116115                }
     116        } else {
     117                ddf_log_debug("SB16 interrupt.\n");
    117118        }
    118119        sb_dsp_interrupt(&drv->dsp);
    119 
    120120}
Note: See TracChangeset for help on using the changeset viewer.