Changeset 9d5244f in mainline for uspace/app/dplay/dplay.c


Ignore:
Timestamp:
2012-07-05T22:17:06Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bb4c141c
Parents:
7364c6ee
Message:

app/dplay: Use event interface properly.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/dplay/dplay.c

    r7364c6ee r9d5244f  
    4040#include <devman.h>
    4141#include <audio_pcm_buffer_iface.h>
     42#include <fibril_synch.h>
    4243#include <stdio.h>
    4344#include <sys/mman.h>
     
    5051
    5152#define DEFAULT_DEVICE "/hw/pci0/00:01.0/sb16/dsp"
    52 #define SUBBUFFERS 4
     53#define SUBBUFFERS 2
    5354
    5455typedef struct {
     
    6061        } buffer;
    6162        FILE* source;
     63        volatile bool playing;
     64        fibril_mutex_t mutex;
     65        fibril_condvar_t cv;
     66        async_exch_t *device;
    6267} playback_t;
    6368
    64 
    65 static void device_event_callback(ipc_callid_t id, ipc_call_t *call, void* arg)
    66 {
    67         if (IPC_GET_IMETHOD(*call) != IPC_FIRST_USER_METHOD) {
    68                 printf("Unknown event.\n");
    69                 return;
    70         }
    71         playback_t *pb = arg;
    72         printf("Got device event!!!\n");
    73         const size_t buffer_part = pb->buffer.size / SUBBUFFERS;
    74         const size_t bytes = fread(pb->buffer.position, sizeof(uint8_t),
    75            buffer_part, pb->source);
    76         if (bytes == 0)
    77                 exit(0); // ugly but temporary
    78         pb->buffer.position += bytes;
    79         if (bytes != buffer_part)
    80                 bzero(pb->buffer.position, buffer_part - bytes);
    81         pb->buffer.position += buffer_part - bytes;
    82         if (pb->buffer.position >= (pb->buffer.base + pb->buffer.size))
    83                 pb->buffer.position = pb->buffer.base;
    84 }
    85 
    86 
    87 static void play(async_exch_t *device, playback_t *pb,
    88     unsigned sampling_rate, unsigned sample_size, unsigned channels, bool sign)
    89 {
    90         assert(device);
     69static void playback_initialize(playback_t *pb, async_exch_t *exch)
     70{
     71        assert(exch);
    9172        assert(pb);
     73        pb->buffer.id = 0;
     74        pb->buffer.base = NULL;
     75        pb->buffer.size = 0;
     76        pb->playing = false;
     77        pb->source = NULL;
     78        pb->device = exch;
     79        fibril_mutex_initialize(&pb->mutex);
     80        fibril_condvar_initialize(&pb->cv);
     81}
     82
     83
     84static void device_event_callback(ipc_callid_t iid, ipc_call_t *icall, void* arg)
     85{
     86        static unsigned wait = SUBBUFFERS;
     87        while (1) {
     88                ipc_call_t call;
     89                ipc_callid_t callid = async_get_call(&call);
     90                if (IPC_GET_IMETHOD(call) != IPC_FIRST_USER_METHOD) {
     91                        printf("Unknown event.\n");
     92                        async_answer_0(callid,EOK);
     93                        break;
     94                }
     95                playback_t *pb = arg;
     96//              printf("Got device event!!!\n");
     97                const size_t buffer_part = pb->buffer.size / SUBBUFFERS;
     98                const size_t bytes = fread(pb->buffer.position, sizeof(uint8_t),
     99                   buffer_part, pb->source);
     100                pb->buffer.position += bytes;
     101                if (bytes != buffer_part)
     102                        bzero(pb->buffer.position, buffer_part - bytes);
     103                pb->buffer.position += buffer_part - bytes;
     104                if (pb->buffer.position >= (pb->buffer.base + pb->buffer.size))
     105                        pb->buffer.position = pb->buffer.base;
     106                async_answer_0(callid,EOK);
     107                if (bytes == 0 && (wait-- == 0)) {
     108                        pb->playing = false;
     109                        fibril_condvar_signal(&pb->cv);
     110                        return;
     111                }
     112        }
     113}
     114
     115
     116static void play(playback_t *pb, unsigned sampling_rate, unsigned sample_size,
     117    unsigned channels, bool sign)
     118{
     119        assert(pb);
     120        assert(pb->device);
    92121        pb->buffer.position = pb->buffer.base;
    93122        printf("Playing: %dHz, %d-bit samples, %d channel(s), %sSIGNED.\n",
     
    98127                return;
    99128        printf("Buffer data ready.\n");
    100         sleep(10);
    101 #if 0
    102         const size_t update_size = size / SUBBUFFERS;
    103 
    104         /* Time to play half the buffer. */
    105         const suseconds_t interval = 1000000 /
    106             (sampling_rate /  (update_size / (channels * (sample_size / 8))));
    107         printf("Time to play half buffer: %ld us.\n", interval);
    108         /* Initialize buffer. */
    109         const size_t bytes = fread(buffer, sizeof(uint8_t), size, source);
    110         if (bytes != size)
    111                 return;
    112 
    113         struct timeval time;
    114         gettimeofday(&time, NULL);
    115         printf("Starting playback.\n");
    116         int ret = audio_pcm_buffer_start_playback(device, buffer_id, SUBBUFFERS,
    117             sampling_rate, sample_size, channels, sign);
    118         if (ret != EOK) {
     129        fibril_mutex_lock(&pb->mutex);
     130        int ret = audio_pcm_buffer_start_playback(pb->device, pb->buffer.id,
     131            SUBBUFFERS, sampling_rate, sample_size, channels, sign);
     132        if (ret != EOK) {
     133                fibril_mutex_unlock(&pb->mutex);
    119134                printf("Failed to start playback: %s.\n", str_error(ret));
    120135                return;
    121136        }
    122         void *buffer_place = buffer;
    123         while (true) {
    124                 tv_add(&time, interval); /* Next update point */
    125 
    126                 struct timeval current;
    127                 gettimeofday(&current, NULL);
    128 
    129                 const suseconds_t delay = min(tv_sub(&time, &current), interval);
    130                 if (delay > 0)
    131                         udelay(delay);
    132 
    133                 const size_t bytes =
    134                     fread(buffer_place, sizeof(uint8_t), update_size, source);
    135                 if (bytes == 0)
    136                         break;
    137                 if (bytes < update_size) {
    138                         bzero(buffer_place + bytes, update_size - bytes);
    139                 }
    140                 buffer_place += update_size;
    141 
    142                 if (buffer_place == buffer + size) {
    143                         buffer_place = buffer;
    144                 }
    145         }
    146 
    147         printf("Stopping playback.\n");
    148         ret = audio_pcm_buffer_stop_playback(device, buffer_id);
    149         if (ret != EOK) {
    150                 printf("Failed to stop playback: %s.\n", str_error(ret));
    151         }
    152 #endif
     137
     138        for (pb->playing = true; pb->playing;
     139          fibril_condvar_wait(&pb->cv, &pb->mutex));
     140
     141        audio_pcm_buffer_stop_playback(pb->device, pb->buffer.id);
    153142}
    154143
     
    202191        free(info);
    203192
    204         playback_t pb = {{0}, NULL};
    205         pb.buffer.size = 4096;
    206         printf("Requesting buffer: %p, %zu, %u.\n", pb.buffer.base, pb.buffer.size, pb.buffer.id);
    207         ret = audio_pcm_buffer_get_buffer(exch, &pb.buffer.base,
     193        playback_t pb;
     194        playback_initialize(&pb, exch);
     195
     196        ret = audio_pcm_buffer_get_buffer(pb.device, &pb.buffer.base,
    208197            &pb.buffer.size, &pb.buffer.id, device_event_callback, &pb);
    209198        if (ret != EOK) {
     
    215204        printf("Buffer (%u): %p %zu.\n", pb.buffer.id, pb.buffer.base,
    216205            pb.buffer.size);
     206        uintptr_t ptr = 0;
     207        as_get_physical_mapping(pb.buffer.base, &ptr);
     208        printf("buffer mapped at %x.\n", ptr);
    217209
    218210        pb.source = fopen(file, "rb");
     
    242234        }
    243235
    244         play(exch, &pb, rate, sample_size, channels, sign);
     236        play(&pb, rate, sample_size, channels, sign);
    245237
    246238        munmap(pb.buffer.base, pb.buffer.size);
Note: See TracChangeset for help on using the changeset viewer.