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) {