Mercurial > repos > blastem
comparison render_sdl.c @ 1684:b1d063466d03
Modified audio code to support an arbitrary number of output channels so that things aren't weird if SDL2 picks a number of channels other than what we ask for
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 18 Jan 2019 00:09:36 -0800 |
parents | 19331a21da3a |
children | 475e84bfccbb |
comparison
equal
deleted
inserted
replaced
1683:7e044a84268d | 1684:b1d063466d03 |
---|---|
43 static uint8_t render_gl = 1; | 43 static uint8_t render_gl = 1; |
44 static uint8_t scanlines = 0; | 44 static uint8_t scanlines = 0; |
45 | 45 |
46 static uint32_t last_frame = 0; | 46 static uint32_t last_frame = 0; |
47 | 47 |
48 static uint8_t output_channels; | |
48 static uint32_t buffer_samples, sample_rate; | 49 static uint32_t buffer_samples, sample_rate; |
49 static uint32_t missing_count; | 50 static uint32_t missing_count; |
50 | 51 |
51 static SDL_mutex * audio_mutex; | 52 static SDL_mutex * audio_mutex; |
52 static SDL_cond * audio_ready; | 53 static SDL_cond * audio_ready; |
81 | 82 |
82 static int32_t mix_s16(audio_source *audio, void *vstream, int len) | 83 static int32_t mix_s16(audio_source *audio, void *vstream, int len) |
83 { | 84 { |
84 int samples = len/(sizeof(int16_t)*2); | 85 int samples = len/(sizeof(int16_t)*2); |
85 int16_t *stream = vstream; | 86 int16_t *stream = vstream; |
86 int16_t *end = stream + 2*samples; | 87 int16_t *end = stream + output_channels*samples; |
87 int16_t *src = audio->front; | 88 int16_t *src = audio->front; |
88 uint32_t i = audio->read_start; | 89 uint32_t i = audio->read_start; |
89 uint32_t i_end = audio->read_end; | 90 uint32_t i_end = audio->read_end; |
90 int16_t *cur = stream; | 91 int16_t *cur = stream; |
92 size_t first_add = output_channels > 1 ? 1 : 0, second_add = output_channels > 1 ? output_channels - 1 : 1; | |
91 if (audio->num_channels == 1) { | 93 if (audio->num_channels == 1) { |
92 while (cur < end && i != i_end) | 94 while (cur < end && i != i_end) |
93 { | 95 { |
94 *(cur++) += src[i]; | 96 *cur += src[i]; |
95 *(cur++) += src[i++]; | 97 cur += first_add; |
98 *cur += src[i++]; | |
99 cur += second_add; | |
96 i &= audio->mask; | 100 i &= audio->mask; |
97 } | 101 } |
98 } else { | 102 } else { |
99 while (cur < end && i != i_end) | 103 while (cur < end && i != i_end) |
100 { | 104 { |
101 *(cur++) += src[i++]; | 105 *cur += src[i++]; |
102 *(cur++) += src[i++]; | 106 cur += first_add; |
107 *cur += src[i++]; | |
108 cur += second_add; | |
103 i &= audio->mask; | 109 i &= audio->mask; |
104 } | 110 } |
105 } | 111 } |
106 | 112 |
107 if (cur != end) { | 113 if (cur != end) { |
125 float *end = stream + 2*samples; | 131 float *end = stream + 2*samples; |
126 int16_t *src = audio->front; | 132 int16_t *src = audio->front; |
127 uint32_t i = audio->read_start; | 133 uint32_t i = audio->read_start; |
128 uint32_t i_end = audio->read_end; | 134 uint32_t i_end = audio->read_end; |
129 float *cur = stream; | 135 float *cur = stream; |
136 size_t first_add = output_channels > 1 ? 1 : 0, second_add = output_channels > 1 ? output_channels - 1 : 1; | |
130 if (audio->num_channels == 1) { | 137 if (audio->num_channels == 1) { |
131 while (cur < end && i != i_end) | 138 while (cur < end && i != i_end) |
132 { | 139 { |
133 *(cur++) += ((float)src[i]) / 0x7FFF; | 140 *cur += ((float)src[i]) / 0x7FFF; |
134 *(cur++) += ((float)src[i++]) / 0x7FFF; | 141 cur += first_add; |
142 *cur += ((float)src[i++]) / 0x7FFF; | |
143 cur += second_add; | |
135 i &= audio->mask; | 144 i &= audio->mask; |
136 } | 145 } |
137 } else { | 146 } else { |
138 while(cur < end && i != i_end) | 147 while(cur < end && i != i_end) |
139 { | 148 { |
140 *(cur++) += ((float)src[i++]) / 0x7FFF; | 149 *cur += ((float)src[i++]) / 0x7FFF; |
141 *(cur++) += ((float)src[i++]) / 0x7FFF; | 150 cur += first_add; |
151 *cur += ((float)src[i++]) / 0x7FFF; | |
152 cur += second_add; | |
142 i &= audio->mask; | 153 i &= audio->mask; |
143 } | 154 } |
144 } | 155 } |
145 if (!sync_to_audio) { | 156 if (!sync_to_audio) { |
146 audio->read_start = i; | 157 audio->read_start = i; |
1025 if (SDL_OpenAudio(&desired, &actual) < 0) { | 1036 if (SDL_OpenAudio(&desired, &actual) < 0) { |
1026 fatal_error("Unable to open SDL audio: %s\n", SDL_GetError()); | 1037 fatal_error("Unable to open SDL audio: %s\n", SDL_GetError()); |
1027 } | 1038 } |
1028 buffer_samples = actual.samples; | 1039 buffer_samples = actual.samples; |
1029 sample_rate = actual.freq; | 1040 sample_rate = actual.freq; |
1041 output_channels = actual.channels; | |
1030 printf("Initialized audio at frequency %d with a %d sample buffer, ", actual.freq, actual.samples); | 1042 printf("Initialized audio at frequency %d with a %d sample buffer, ", actual.freq, actual.samples); |
1031 if (actual.format == AUDIO_S16SYS) { | 1043 if (actual.format == AUDIO_S16SYS) { |
1032 puts("signed 16-bit int format"); | 1044 puts("signed 16-bit int format"); |
1033 mix = mix_s16; | 1045 mix = mix_s16; |
1034 } else if (actual.format == AUDIO_F32SYS) { | 1046 } else if (actual.format == AUDIO_F32SYS) { |