Changeset d26233c in mainline
- Timestamp:
- 2013-04-07T09:46:59Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e1d2f0e
- Parents:
- 7db073f
- Location:
- uspace/app/wavplay
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/wavplay/Makefile
r7db073f rd26233c 32 32 LIBS = \ 33 33 $(LIBHOUND_PREFIX)/libhound.a \ 34 $(LIBDRV_PREFIX)/libdrv.a 34 $(LIBDRV_PREFIX)/libdrv.a \ 35 $(LIBPCM_PREFIX)/libpcm.a 35 36 36 37 EXTRA_CFLAGS = \ -
uspace/app/wavplay/main.c
r7db073f rd26233c 37 37 #include <errno.h> 38 38 #include <fibril_synch.h> 39 #include <malloc.h> 39 40 #include <str_error.h> 40 41 #include <stdio.h> … … 46 47 #include "wave.h" 47 48 48 #define BUFFER_SIZE(32 * 1024)49 50 51 static int hplay (const char *filename)52 { 53 printf("Hound playback: %s\n", filename);49 #define READ_SIZE (32 * 1024) 50 #define STREAM_BUFFER_SIZE (64 * 1024) 51 52 static int hplay_ctx(hound_context_t *ctx, const char *filename) 53 { 54 printf("Hound context playback: %s\n", filename); 54 55 FILE *source = fopen(filename, "rb"); 55 56 if (!source) { … … 73 74 return EINVAL; 74 75 } 76 77 hound_stream_t *stream = hound_stream_create(ctx, 78 HOUND_STREAM_DRAIN_ON_EXIT, format, STREAM_BUFFER_SIZE); 79 80 char * buffer = malloc(READ_SIZE); 81 if (!buffer) { 82 fclose(source); 83 return ENOMEM; 84 } 85 while ((read = fread(buffer, sizeof(char), READ_SIZE, source)) > 0) { 86 ret = hound_stream_write(stream, buffer, read); 87 if (ret != EOK) { 88 printf("Failed to write to hound stream: %s\n", 89 str_error(ret)); 90 break; 91 } 92 } 93 free(buffer); 94 fclose(source); 95 return ret; 96 } 97 98 static int hplay(const char *filename) 99 { 100 printf("Hound playback: %s\n", filename); 101 FILE *source = fopen(filename, "rb"); 102 if (!source) { 103 printf("Failed to open file %s\n", filename); 104 return EINVAL; 105 } 106 wave_header_t header; 107 size_t read = fread(&header, sizeof(header), 1, source); 108 if (read != 1) { 109 printf("Failed to read WAV header: %zu\n", read); 110 fclose(source); 111 return EIO; 112 } 113 pcm_format_t format; 114 const char *error; 115 int ret = wav_parse_header(&header, NULL, NULL, &format.channels, 116 &format.sampling_rate, &format.sample_format, &error); 117 if (ret != EOK) { 118 printf("Error parsing wav header: %s.\n", error); 119 fclose(source); 120 return EINVAL; 121 } 75 122 hound_context_t *hound = hound_context_create_playback(filename, 76 format, BUFFER_SIZE * 2);123 format, STREAM_BUFFER_SIZE); 77 124 if (!hound) { 78 125 printf("Failed to create HOUND context\n"); … … 89 136 return ret; 90 137 } 91 static char buffer[ BUFFER_SIZE];92 while ((read = fread(buffer, sizeof(char), BUFFER_SIZE, source)) > 0) {138 static char buffer[READ_SIZE]; 139 while ((read = fread(buffer, sizeof(char), READ_SIZE, source)) > 0) { 93 140 ret = hound_write_main_stream(hound, buffer, read); 94 141 if (ret != EOK) { … … 103 150 } 104 151 152 typedef struct { 153 hound_context_t *ctx; 154 atomic_t *count; 155 const char *file; 156 } fib_play_t; 157 158 static int play_wrapper(void *arg) 159 { 160 assert(arg); 161 fib_play_t *p = arg; 162 const int ret = hplay_ctx(p->ctx, p->file); 163 atomic_dec(p->count); 164 free(arg); 165 return ret; 166 } 167 105 168 static const struct option opts[] = { 106 169 {"device", required_argument, 0, 'd'}, 170 {"parallel", no_argument, 0, 'p'}, 107 171 {"record", no_argument, 0, 'r'}, 108 172 {"help", no_argument, 0, 'h'}, … … 119 183 printf("\t -d, --device\t Use specified device instead of the sound " 120 184 "service. Use location path or a special device `default'\n"); 185 printf("\t -p, --parallel\t Play given files in parallel instead of " 186 "sequentially (does not work with -d).\n"); 121 187 } 122 188 … … 125 191 const char *device = "default"; 126 192 int idx = 0; 127 bool direct = false, record = false ;193 bool direct = false, record = false, parallel = false; 128 194 optind = 0; 129 195 int ret = 0; 130 196 while (ret != -1) { 131 ret = getopt_long(argc, argv, "d: rh", opts, &idx);197 ret = getopt_long(argc, argv, "d:prh", opts, &idx); 132 198 switch (ret) { 133 199 case 'd': … … 138 204 record = true; 139 205 break; 206 case 'p': 207 parallel = true; 208 break; 140 209 case 'h': 141 210 print_help(*argv); … … 144 213 } 145 214 215 if (parallel && direct) { 216 printf("Parallel playback is available only if using sound " 217 "server (no -d)\n"); 218 print_help(*argv); 219 return 1; 220 } 221 146 222 if (optind == argc) { 147 223 printf("Not enough arguments.\n"); 148 224 print_help(*argv); 149 225 return 1; 226 } 227 228 hound_context_t *hound_ctx = NULL; 229 atomic_t playcount; 230 atomic_set(&playcount, 0); 231 if (parallel) { 232 hound_ctx = hound_context_create_playback("wavplay", 233 AUDIO_FORMAT_DEFAULT, STREAM_BUFFER_SIZE); 234 if (!hound_ctx) { 235 printf("Failed to create global hound context\n"); 236 return 1; 237 } 238 const int ret = hound_context_connect_target(hound_ctx, 239 HOUND_DEFAULT_TARGET); 240 if (ret != EOK) { 241 printf("Failed to connect hound context to default " 242 "target.\n"); 243 hound_context_destroy(hound_ctx); 244 return 1; 245 } 150 246 } 151 247 … … 162 258 dplay(device, file); 163 259 } else { 164 hplay(file); 165 } 166 } 260 if (parallel) { 261 fib_play_t *data = malloc(sizeof(fib_play_t)); 262 if (!data) { 263 printf("Playback of %s failed.\n", 264 file); 265 continue; 266 } 267 data->file = file; 268 data->count = &playcount; 269 data->ctx = hound_ctx; 270 fid_t fid = fibril_create(play_wrapper, data); 271 atomic_inc(&playcount); 272 fibril_add_ready(fid); 273 } else { 274 hplay(file); 275 } 276 } 277 } 278 279 while (atomic_get(&playcount) > 0) 280 async_usleep(1000000); 281 282 if (hound_ctx) 283 hound_context_destroy(hound_ctx); 167 284 return 0; 168 285 }
Note:
See TracChangeset
for help on using the changeset viewer.