Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 5cd5079 in mainline


Ignore:
Timestamp:
2012-07-15T15:44:20Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial
Children:
63c34d7
Parents:
57e8b3b
Message:

app/wavplay: Use libhound

Location:
uspace/app/wavplay
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/wavplay/Makefile

    r57e8b3b r5cd5079  
    3131
    3232LIBS = \
     33        $(LIBHOUND_PREFIX)/libhound.a
    3334
    3435EXTRA_CFLAGS = \
     36        -I $(LIBHOUND_PREFIX)/include
    3537
    3638SOURCES = \
  • uspace/app/wavplay/wavplay.c

    r57e8b3b r5cd5079  
    3434 */
    3535
    36 #include <async.h>
    3736#include <assert.h>
    3837#include <errno.h>
     38#include <fibril_synch.h>
    3939#include <str_error.h>
    40 #include <str.h>
    41 #include <devman.h>
    42 #include <fibril_synch.h>
    4340#include <stdio.h>
    44 #include <sys/mman.h>
    45 #include <loc.h>
     41
     42#include <hound/client.h>
    4643
    4744#include <pcm_sample_format.h>
    4845
    4946#include <stdio.h>
    50 #include <macros.h>
    5147
    5248#include "wave.h"
    5349
    54 #define SERVICE "audio/hound"
    55 #define DEFAULT_DEVICE "default" //"devices/\\hw\\pci0\\00:01.0\\sb16\\pcm"
    56 #define SUBBUFFERS 2
    5750#define NAME_MAX 32
    5851char name[NAME_MAX + 1];
    5952
    6053typedef struct {
    61         struct {
    62                 void *base;
    63                 size_t size;
    64                 unsigned id;
    65                 void* position;
    66         } buffer;
    6754        FILE* source;
    6855        volatile bool playing;
    6956        fibril_mutex_t mutex;
    7057        fibril_condvar_t cv;
    71         async_exch_t *server;
     58        hound_sess_t *server;
    7259} playback_t;
    7360
    74 static void playback_initialize(playback_t *pb, async_exch_t *exch)
     61static void playback_initialize(playback_t *pb, hound_sess_t *sess)
    7562{
    76         assert(exch);
    7763        assert(pb);
    78         pb->buffer.id = 0;
    79         pb->buffer.base = NULL;
    80         pb->buffer.size = 0;
    81         pb->buffer.position = NULL;
    8264        pb->playing = false;
    8365        pb->source = NULL;
    84         pb->server = exch;
     66        pb->server = sess;
    8567        fibril_mutex_initialize(&pb->mutex);
    8668        fibril_condvar_initialize(&pb->cv);
     
    8870
    8971
    90 static void data_callback(ipc_callid_t iid, ipc_call_t *icall, void* arg)
     72static void data_callback(void* arg, void *buffer, ssize_t size)
    9173{
    92         async_answer_0(iid, EOK);
    9374        playback_t *pb = arg;
     75        assert(pb);
    9476
    95         while (1) {
    96                 size_t size = 0;
    97                 if (!async_data_read_receive(&iid, &size)) {
    98                         printf("Data request failed");
    99                         continue;
     77        if (size > 0) {
     78                const ssize_t bytes =
     79                    fread(buffer, sizeof(uint8_t), size, pb->source);
     80                printf("%zu bytes ready\n", bytes);
     81                if (bytes < size) {
     82                        printf(" requested: %zd ready: %zd zero: %zd\n",
     83                                size, bytes, size - bytes);
     84                        bzero(buffer + bytes, size - bytes);
    10085                }
    101 //              printf("Server asked for more(%zu) data\n", size);
    102                 if (pb->buffer.size < size) {
    103                         printf("Reallocating buffer: %zu -> %zu\n",
    104                             pb->buffer.size, size);
    105                         pb->buffer.base = realloc(pb->buffer.base, size);
    106                         pb->buffer.size = size;
    107                 }
    108                 const size_t bytes = fread(pb->buffer.base, sizeof(uint8_t),
    109                    size, pb->source);
    110 //              printf("%zu bytes ready\n", bytes);
    111                 if (bytes < pb->buffer.size) {
    112                         bzero(pb->buffer.base + bytes, size - bytes);
    113                 }
    114                 async_data_read_finalize(iid, pb->buffer.base, size);
    11586                if (bytes == 0) {
    116                         /* Disconnect */
    117                         aid_t id = async_send_0(pb->server,
    118                             IPC_FIRST_USER_METHOD + 5, NULL);
    119                         async_data_write_start(pb->server, name, str_size(name) + 1);
    120                         async_data_write_start(pb->server, DEFAULT_DEVICE,
    121                             1+str_size(DEFAULT_DEVICE));
    122                         async_wait_for(id, NULL);
    123 
    124                         printf("\nPlayback terminated\n");
    125                         fibril_mutex_lock(&pb->mutex);
    12687                        pb->playing = false;
    12788                        fibril_condvar_signal(&pb->cv);
    128                         fibril_mutex_unlock(&pb->mutex);
    129                         return;
    13089                }
    131 
     90        } else {
     91                printf("Got error %s.\n", str_error(size));
     92                pb->playing = false;
     93                fibril_condvar_signal(&pb->cv);
    13294        }
    13395}
     
    13799        assert(pb);
    138100        /* Create playback client */
    139         aid_t id = async_send_3(pb->server, IPC_FIRST_USER_METHOD, channels,
    140             rate, format, NULL);
    141         int ret = async_data_write_start(pb->server, name, str_size(name) + 1);
     101        int ret = hound_register_playback(pb->server, name, channels, rate,
     102            format, data_callback, pb);
    142103        if (ret != EOK) {
    143                 printf("Failed to send client name: %s\n", str_error(ret));
    144                 async_forget(id);
    145                 return;
    146         }
    147         ret = async_connect_to_me(pb->server, 0, 0, 0, data_callback, pb);
    148         if (ret != EOK) {
    149                 printf("Failed to establish callback: %s\n", str_error(ret));
    150                 async_forget(id);
    151                 return;
    152         }
    153         async_wait_for(id, (sysarg_t*)&ret);
    154         if (ret != EOK) {
    155                 printf("Failed to create client: %s\n", str_error(ret));
    156                 async_forget(id);
     104                printf("Failed to register playback: %s\n", str_error(ret));
    157105                return;
    158106        }
    159107
    160108        /* Connect */
    161         id = async_send_0(pb->server, IPC_FIRST_USER_METHOD + 4, NULL);
    162         async_data_write_start(pb->server, name, str_size(name) + 1);
    163         async_data_write_start(pb->server, DEFAULT_DEVICE, 1+str_size(DEFAULT_DEVICE));
    164         async_wait_for(id, NULL);
     109        ret = hound_create_connection(pb->server, name, DEFAULT_SINK);
     110        if (ret == EOK) {
     111                fibril_mutex_lock(&pb->mutex);
     112                for (pb->playing = true; pb->playing;
     113                    fibril_condvar_wait(&pb->cv, &pb->mutex));
     114                fibril_mutex_unlock(&pb->mutex);
    165115
    166         fibril_mutex_lock(&pb->mutex);
     116                hound_destroy_connection(pb->server, name, DEFAULT_SINK);
     117        } else
     118                printf("Failed to connect: %s\n", str_error(ret));
    167119
    168         for (pb->playing = true; pb->playing;
    169             fibril_condvar_wait(&pb->cv, &pb->mutex));
    170         fibril_mutex_unlock(&pb->mutex);
     120        hound_unregister_playback(pb->server, name);
    171121}
    172122
     
    177127        const char *file = argv[1];
    178128
    179         service_id_t id = 0;
    180         int ret = loc_service_get_id(SERVICE, &id, 0);
    181         if (ret != EOK) {
    182                 printf("Failed to get hound service id\n");
    183                 return 1;
    184         }
    185 
    186129        task_id_t tid = task_get_id();
    187130        snprintf(name, NAME_MAX, "%s%" PRIu64 ":%s", argv[0], tid, file);
     
    189132        printf("Client name: %s\n", name);
    190133
    191         async_sess_t *sess = loc_service_connect(EXCHANGE_SERIALIZE, id, 0);
     134        hound_sess_t *sess = hound_get_session();
    192135        if (!sess) {
    193136                printf("Failed to connect to hound service\n");
     
    195138        }
    196139
    197         async_exch_t *exch = async_exchange_begin(sess);
    198         if (!exch) {
    199                 printf("Failed to create exchange\n");
    200                 async_hangup(sess);
    201                 return 1;
    202         }
    203 
    204 
    205140        playback_t pb;
    206         playback_initialize(&pb, exch);
     141        playback_initialize(&pb, sess);
    207142        pb.source = fopen(file, "rb");
    208143        if (pb.source == NULL) {
    209                 ret = ENOENT;
    210144                printf("Failed to open %s.\n", file);
    211                 goto cleanup;
     145                hound_release_session(sess);
     146                return 1;
    212147        }
    213148        wave_header_t header;
     
    216151        pcm_sample_format_t format;
    217152        const char *error;
    218         ret = wav_parse_header(&header, NULL, NULL, &channels, &rate, &format,
    219             &error);
     153        const int ret = wav_parse_header(&header, NULL, NULL, &channels, &rate,
     154            &format, &error);
    220155        if (ret != EOK) {
    221156                printf("Error parsing wav header: %s.\n", error);
    222157                fclose(pb.source);
    223                 goto cleanup;
     158                hound_release_session(sess);
     159                return 1;
    224160        }
    225161
    226162        play(&pb, channels, rate, format);
    227163
    228 cleanup:
    229         async_exchange_end(exch);
    230 
    231         async_hangup(sess);
    232 
     164        hound_release_session(sess);
    233165        return 0;
    234166}
Note: See TracChangeset for help on using the changeset viewer.