Changeset 5cd5079 in mainline
- Timestamp:
- 2012-07-15T15:44:20Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63c34d7
- Parents:
- 57e8b3b
- Location:
- uspace/app/wavplay
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/wavplay/Makefile
r57e8b3b r5cd5079 31 31 32 32 LIBS = \ 33 $(LIBHOUND_PREFIX)/libhound.a 33 34 34 35 EXTRA_CFLAGS = \ 36 -I $(LIBHOUND_PREFIX)/include 35 37 36 38 SOURCES = \ -
uspace/app/wavplay/wavplay.c
r57e8b3b r5cd5079 34 34 */ 35 35 36 #include <async.h>37 36 #include <assert.h> 38 37 #include <errno.h> 38 #include <fibril_synch.h> 39 39 #include <str_error.h> 40 #include <str.h>41 #include <devman.h>42 #include <fibril_synch.h>43 40 #include <stdio.h> 44 #include <sys/mman.h> 45 #include < loc.h>41 42 #include <hound/client.h> 46 43 47 44 #include <pcm_sample_format.h> 48 45 49 46 #include <stdio.h> 50 #include <macros.h>51 47 52 48 #include "wave.h" 53 49 54 #define SERVICE "audio/hound"55 #define DEFAULT_DEVICE "default" //"devices/\\hw\\pci0\\00:01.0\\sb16\\pcm"56 #define SUBBUFFERS 257 50 #define NAME_MAX 32 58 51 char name[NAME_MAX + 1]; 59 52 60 53 typedef struct { 61 struct {62 void *base;63 size_t size;64 unsigned id;65 void* position;66 } buffer;67 54 FILE* source; 68 55 volatile bool playing; 69 56 fibril_mutex_t mutex; 70 57 fibril_condvar_t cv; 71 async_exch_t *server;58 hound_sess_t *server; 72 59 } playback_t; 73 60 74 static void playback_initialize(playback_t *pb, async_exch_t *exch)61 static void playback_initialize(playback_t *pb, hound_sess_t *sess) 75 62 { 76 assert(exch);77 63 assert(pb); 78 pb->buffer.id = 0;79 pb->buffer.base = NULL;80 pb->buffer.size = 0;81 pb->buffer.position = NULL;82 64 pb->playing = false; 83 65 pb->source = NULL; 84 pb->server = exch;66 pb->server = sess; 85 67 fibril_mutex_initialize(&pb->mutex); 86 68 fibril_condvar_initialize(&pb->cv); … … 88 70 89 71 90 static void data_callback( ipc_callid_t iid, ipc_call_t *icall, void* arg)72 static void data_callback(void* arg, void *buffer, ssize_t size) 91 73 { 92 async_answer_0(iid, EOK);93 74 playback_t *pb = arg; 75 assert(pb); 94 76 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); 100 85 } 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);115 86 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);126 87 pb->playing = false; 127 88 fibril_condvar_signal(&pb->cv); 128 fibril_mutex_unlock(&pb->mutex);129 return;130 89 } 131 90 } else { 91 printf("Got error %s.\n", str_error(size)); 92 pb->playing = false; 93 fibril_condvar_signal(&pb->cv); 132 94 } 133 95 } … … 137 99 assert(pb); 138 100 /* 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); 142 103 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)); 157 105 return; 158 106 } 159 107 160 108 /* 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); 165 115 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)); 167 119 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); 171 121 } 172 122 … … 177 127 const char *file = argv[1]; 178 128 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 186 129 task_id_t tid = task_get_id(); 187 130 snprintf(name, NAME_MAX, "%s%" PRIu64 ":%s", argv[0], tid, file); … … 189 132 printf("Client name: %s\n", name); 190 133 191 async_sess_t *sess = loc_service_connect(EXCHANGE_SERIALIZE, id, 0);134 hound_sess_t *sess = hound_get_session(); 192 135 if (!sess) { 193 136 printf("Failed to connect to hound service\n"); … … 195 138 } 196 139 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 205 140 playback_t pb; 206 playback_initialize(&pb, exch);141 playback_initialize(&pb, sess); 207 142 pb.source = fopen(file, "rb"); 208 143 if (pb.source == NULL) { 209 ret = ENOENT;210 144 printf("Failed to open %s.\n", file); 211 goto cleanup; 145 hound_release_session(sess); 146 return 1; 212 147 } 213 148 wave_header_t header; … … 216 151 pcm_sample_format_t format; 217 152 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); 220 155 if (ret != EOK) { 221 156 printf("Error parsing wav header: %s.\n", error); 222 157 fclose(pb.source); 223 goto cleanup; 158 hound_release_session(sess); 159 return 1; 224 160 } 225 161 226 162 play(&pb, channels, rate, format); 227 163 228 cleanup: 229 async_exchange_end(exch); 230 231 async_hangup(sess); 232 164 hound_release_session(sess); 233 165 return 0; 234 166 }
Note:
See TracChangeset
for help on using the changeset viewer.