Here is what I did in my recent synthesizer project.
int* unfiltered = (int *)malloc(lengthOfLongPcmInShorts*4); int i; for(i = 0; i < lengthOfShortPcmInShorts; i++){ unfiltered[i] = shortPcm[i] + longPcm[i]; } for(; i < lengthOfLongPcmInShorts; i++){ unfiltered[i] = longPcm[i]; } int max = 0; for(int i = 0; i < lengthOfLongPcmInShorts; i++){ int val = unfiltered[i]; if(abs(val) > max) max = val; } short int *newPcm = (short int *)malloc(lengthOfLongPcmInShorts*2); for(int i = 0; i < lengthOfLongPcmInShorts; i++){ newPcm[i] = (unfilted[i]/max) * MAX_SHRT; }
I added all the PCM data to an integer array, so that I get all the data without filtering.
After that, I searched for the absolute maximum value in the integer array.
Finally, I took an integer array and placed it in a short int array, dividing each element by this maximum value and then multiplying it by the maximum short int value.
This way you get the minimum amount of "stock" needed to match the data.
You might be able to do some statistics on an integer array and integrate some clippings, but for what I needed, the minimum amount of margin was good enough for me.
source share