Changeset 017455e in mainline
- Timestamp:
- 2012-08-30T19:36:14Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b5d2e57
- Parents:
- e1534533
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/wavplay/dplay.c
re1534533 r017455e 41 41 #include <audio_pcm_iface.h> 42 42 #include <fibril_synch.h> 43 #include < stdio.h>43 #include <pcm/format.h> 44 44 #include <sys/mman.h> 45 45 #include <sys/time.h> … … 60 60 void* position; 61 61 } buffer; 62 pcm_format_t f; 62 63 FILE* source; 63 64 volatile bool playing; … … 86 87 async_answer_0(iid, EOK); 87 88 playback_t *pb = arg; 88 const size_t buffer_part= pb->buffer.size / BUFFER_PARTS;89 const size_t fragment_size = pb->buffer.size / BUFFER_PARTS; 89 90 while (1) { 90 91 ipc_call_t call; … … 93 94 case PCM_EVENT_PLAYBACK_STARTED: 94 95 case PCM_EVENT_FRAMES_PLAYED: 95 printf("%u frames \n", IPC_GET_ARG1(call));96 printf("%u frames: ", IPC_GET_ARG1(call)); 96 97 async_answer_0(callid, EOK); 97 98 break; … … 111 112 } 112 113 const size_t bytes = fread(pb->buffer.position, sizeof(uint8_t), 113 buffer_part, pb->source); 114 fragment_size, pb->source); 115 printf("Copied from position %p size %zu/%zu\n", 116 pb->buffer.position, bytes, fragment_size); 114 117 if (bytes == 0) { 115 118 audio_pcm_last_playback_fragment(pb->device); 116 119 } 117 bzero(pb->buffer.position + bytes, buffer_part- bytes);118 pb->buffer.position += buffer_part;120 bzero(pb->buffer.position + bytes, fragment_size - bytes); 121 pb->buffer.position += fragment_size; 119 122 120 123 if (pb->buffer.position >= (pb->buffer.base + pb->buffer.size)) 121 pb->buffer.position = pb->buffer.base; 122 } 123 } 124 125 126 static void play(playback_t *pb, unsigned channels, unsigned sampling_rate, 127 pcm_sample_format_t format) 124 pb->buffer.position -= pb->buffer.size; 125 } 126 } 127 128 static void play_fragment(playback_t *pb) 128 129 { 129 130 assert(pb); 130 131 assert(pb->device); 131 const size_t buffer_part = pb->buffer.size / BUFFER_PARTS; 132 pb->buffer.position = pb->buffer.base + buffer_part; 132 const size_t fragment_size = pb->buffer.size / BUFFER_PARTS; 133 133 printf("Registering event callback\n"); 134 134 int ret = audio_pcm_register_event_callback(pb->device, … … 138 138 return; 139 139 } 140 printf("Playing: %dHz, %s, %d channel(s).\n", 141 sampling_rate, pcm_sample_format_str(format),channels);140 printf("Playing: %dHz, %s, %d channel(s).\n", pb->f.sampling_rate, 141 pcm_sample_format_str(pb->f.sample_format), pb->f.channels); 142 142 const size_t bytes = fread(pb->buffer.base, sizeof(uint8_t), 143 buffer_part, pb->source); 144 if (bytes != buffer_part) 145 bzero(pb->buffer.base + bytes, buffer_part - bytes); 146 printf("Buffer data ready.\n"); 143 fragment_size, pb->source); 144 if (bytes != fragment_size) 145 bzero(pb->buffer.base + bytes, fragment_size - bytes); 146 printf("Initial: Copied from position %p size %zu/%zu\n", 147 pb->buffer.base, bytes, fragment_size); 148 pb->buffer.position = pb->buffer.base + fragment_size; 147 149 fibril_mutex_lock(&pb->mutex); 148 const unsigned frames = pb->buffer.size / 149 (BUFFER_PARTS * channels * pcm_sample_format_size(format)); 150 ret = audio_pcm_start_playback_fragment(pb->device, frames, channels, 151 sampling_rate, format); 150 const unsigned frames = pcm_format_size_to_frames(fragment_size, &pb->f); 151 ret = audio_pcm_start_playback_fragment(pb->device, frames, 152 pb->f.channels, pb->f.sampling_rate, pb->f.sample_format); 152 153 if (ret != EOK) { 153 154 fibril_mutex_unlock(&pb->mutex); 154 155 printf("Failed to start playback: %s.\n", str_error(ret)); 156 audio_pcm_unregister_event_callback(pb->device); 155 157 return; 156 158 } … … 164 166 } 165 167 168 static void play(playback_t *pb) 169 { 170 assert(pb); 171 assert(pb->device); 172 pb->buffer.position = pb->buffer.base; 173 printf("Playing: %dHz, %s, %d channel(s).\n", pb->f.sampling_rate, 174 pcm_sample_format_str(pb->f.sample_format), pb->f.channels); 175 static suseconds_t work_time = 8000; /* 2 ms */ 176 size_t bytes = fread(pb->buffer.position, sizeof(uint8_t), 177 pb->buffer.size, pb->source); 178 if (bytes == 0) 179 return; 180 audio_pcm_start_playback(pb->device, 181 pb->f.channels, pb->f.sampling_rate, pb->f.sample_format); 182 do { 183 size_t pos = 0; 184 audio_pcm_get_buffer_pos(pb->device, &pos); 185 useconds_t usecs = pcm_format_size_to_usec(bytes - pos, &pb->f); 186 187 pb->buffer.position += bytes; 188 189 printf("%u usecs to play %zu bytes from pos %zu.\n", 190 usecs, bytes, pos); 191 async_usleep(usecs - work_time); 192 audio_pcm_get_buffer_pos(pb->device, &pos); 193 printf("Woke up at position %zu/%zu.\n", pos, pb->buffer.size); 194 195 /* Remove any overflow */ 196 while (pb->buffer.position >= pb->buffer.base + pb->buffer.size) 197 pb->buffer.position -= pb->buffer.size; 198 199 if (bytes < pb->buffer.size) { 200 const size_t remain = pb->buffer.size - 201 (pb->buffer.position - pb->buffer.base); 202 /* This was the last part, 203 * zero 200 bytes or until the end of buffer. */ 204 bzero(pb->buffer.position, min(200, remain)); 205 if ((pb->buffer.base + pos) > pb->buffer.position) { 206 printf("Overflow: %zu vs. %zu!\n", 207 pos, pb->buffer.position - pb->buffer.base); 208 } else { 209 udelay(pcm_format_size_to_usec( 210 pb->buffer.position - pb->buffer.base - pos, 211 &pb->f)); 212 audio_pcm_get_buffer_pos(pb->device, &pos); 213 } 214 printf("Stopped at %zu(%zu)/%zu\n", 215 pos, pb->buffer.position - pb->buffer.base, 216 pb->buffer.size); 217 break; 218 } 219 /* copy first half */ 220 bytes = fread(pb->buffer.position, sizeof(uint8_t), 221 pb->buffer.size / 2, pb->source); 222 if (bytes == 0) 223 break; 224 audio_pcm_get_buffer_pos(pb->device, &pos); 225 printf("Half buffer copied at pos %zu", pos); 226 /* Wait until the rest of the buffer is ready */ 227 udelay(pcm_format_size_to_usec(pb->buffer.size - pos, &pb->f)); 228 /* copy the other part of the buffer */ 229 audio_pcm_get_buffer_pos(pb->device, &pos); 230 printf(" the other half copied at pos %zu\n", pos); 231 bytes += fread(pb->buffer.position + bytes, sizeof(uint8_t), 232 pb->buffer.size / 2, pb->source); 233 } while (1); 234 audio_pcm_stop_playback(pb->device); 235 } 236 166 237 int dplay(const char *device, const char *file) 167 238 { 239 int ret = EOK; 168 240 if (str_cmp(device, "default") == 0) 169 241 device = DEFAULT_DEVICE; … … 174 246 } 175 247 printf("Playing on device: %s.\n", device); 248 if (audio_pcm_query_cap(session, AUDIO_CAP_PLAYBACK) <= 0) { 249 printf("Device %s does not support playback\n", device); 250 ret = ENOTSUP; 251 goto close_session; 252 } 176 253 177 254 const char* info = NULL; 178 intret = audio_pcm_get_info_str(session, &info);255 ret = audio_pcm_get_info_str(session, &info); 179 256 if (ret != EOK) { 180 257 printf("Failed to get PCM info.\n"); … … 205 282 wave_header_t header; 206 283 fread(&header, sizeof(header), 1, pb.source); 207 unsigned rate, channels;208 pcm_sample_format_t format;209 284 const char *error; 210 ret = wav_parse_header(&header, NULL, NULL, &channels, &rate, &format,211 & error);285 ret = wav_parse_header(&header, NULL, NULL, 286 &pb.f.channels, &pb.f.sampling_rate, &pb.f.sample_format, &error); 212 287 if (ret != EOK) { 213 288 printf("Error parsing wav header: %s.\n", error); … … 215 290 goto cleanup; 216 291 } 217 218 play(&pb, channels, rate, format); 292 if (audio_pcm_query_cap(pb.device, AUDIO_CAP_BUFFER_POS) > 0) { 293 play(&pb); 294 } else { 295 if (audio_pcm_query_cap(pb.device, AUDIO_CAP_INTERRUPT) > 0) 296 play_fragment(&pb); 297 else 298 printf("Neither playing method is supported"); 299 } 300 301 cleanup: 219 302 fclose(pb.source); 220 221 cleanup:222 303 munmap(pb.buffer.base, pb.buffer.size); 223 304 audio_pcm_release_buffer(pb.device);
Note:
See TracChangeset
for help on using the changeset viewer.