Changeset dce7e41 in mainline for uspace/drv/audio/sb16/dsp.c


Ignore:
Timestamp:
2011-10-21T21:59:30Z (13 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.

File:
1 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/**
Note: See TracChangeset for help on using the changeset viewer.