Changeset 9d5244f in mainline
- Timestamp:
- 2012-07-05T22:17:06Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bb4c141c
- Parents:
- 7364c6ee
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/dplay/dplay.c
r7364c6ee r9d5244f 40 40 #include <devman.h> 41 41 #include <audio_pcm_buffer_iface.h> 42 #include <fibril_synch.h> 42 43 #include <stdio.h> 43 44 #include <sys/mman.h> … … 50 51 51 52 #define DEFAULT_DEVICE "/hw/pci0/00:01.0/sb16/dsp" 52 #define SUBBUFFERS 453 #define SUBBUFFERS 2 53 54 54 55 typedef struct { … … 60 61 } buffer; 61 62 FILE* source; 63 volatile bool playing; 64 fibril_mutex_t mutex; 65 fibril_condvar_t cv; 66 async_exch_t *device; 62 67 } playback_t; 63 68 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); 69 static void playback_initialize(playback_t *pb, async_exch_t *exch) 70 { 71 assert(exch); 91 72 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 84 static 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 116 static void play(playback_t *pb, unsigned sampling_rate, unsigned sample_size, 117 unsigned channels, bool sign) 118 { 119 assert(pb); 120 assert(pb->device); 92 121 pb->buffer.position = pb->buffer.base; 93 122 printf("Playing: %dHz, %d-bit samples, %d channel(s), %sSIGNED.\n", … … 98 127 return; 99 128 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); 119 134 printf("Failed to start playback: %s.\n", str_error(ret)); 120 135 return; 121 136 } 122 void *buffer_place = buffer; 123 while (true) { 124 tv_add(&time, interval); /* Next update point */ 125 126 struct timeval current; 127 gettimeofday(¤t, NULL); 128 129 const suseconds_t delay = min(tv_sub(&time, ¤t), 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); 153 142 } 154 143 … … 202 191 free(info); 203 192 204 playback_t pb = {{0}, NULL};205 p b.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, 208 197 &pb.buffer.size, &pb.buffer.id, device_event_callback, &pb); 209 198 if (ret != EOK) { … … 215 204 printf("Buffer (%u): %p %zu.\n", pb.buffer.id, pb.buffer.base, 216 205 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); 217 209 218 210 pb.source = fopen(file, "rb"); … … 242 234 } 243 235 244 play( exch,&pb, rate, sample_size, channels, sign);236 play(&pb, rate, sample_size, channels, sign); 245 237 246 238 munmap(pb.buffer.base, pb.buffer.size);
Note:
See TracChangeset
for help on using the changeset viewer.