gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

pa_win_waveformat.c (6385B)


      1 /*
      2  * PortAudio Portable Real-Time Audio Library
      3  * Windows WAVEFORMAT* data structure utilities
      4  * portaudio.h should be included before this file.
      5  *
      6  * Copyright (c) 2007 Ross Bencina
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining
      9  * a copy of this software and associated documentation files
     10  * (the "Software"), to deal in the Software without restriction,
     11  * including without limitation the rights to use, copy, modify, merge,
     12  * publish, distribute, sublicense, and/or sell copies of the Software,
     13  * and to permit persons to whom the Software is furnished to do so,
     14  * subject to the following conditions:
     15  *
     16  * The above copyright notice and this permission notice shall be
     17  * included in all copies or substantial portions of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
     24  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     25  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  */
     27 
     28 /*
     29  * The text above constitutes the entire PortAudio license; however, 
     30  * the PortAudio community also makes the following non-binding requests:
     31  *
     32  * Any person wishing to distribute modifications to the Software is
     33  * requested to send the modifications to the original developer so that
     34  * they can be incorporated into the canonical version. It is also 
     35  * requested that these non-binding requests be included along with the 
     36  * license above.
     37  */
     38 
     39 #include <windows.h>
     40 #include <mmsystem.h>
     41 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
     42     #include <mmreg.h> /* for WAVEFORMATEX */
     43 #endif
     44 
     45 #include "portaudio.h"
     46 #include "pa_win_waveformat.h"
     47 
     48 
     49 #if !defined(WAVE_FORMAT_EXTENSIBLE)
     50 #define  WAVE_FORMAT_EXTENSIBLE         0xFFFE
     51 #endif
     52 
     53 
     54 static GUID pawin_ksDataFormatSubtypeGuidBase = 
     55 	{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
     56 
     57 
     58 int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat )
     59 {
     60     if( sampleFormat == paFloat32 )
     61         return PAWIN_WAVE_FORMAT_IEEE_FLOAT;
     62     
     63     return PAWIN_WAVE_FORMAT_PCM;
     64 }
     65 
     66 
     67 void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, 
     68 		int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate )
     69 {
     70 	WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
     71     int bytesPerSample = Pa_GetSampleSize(sampleFormat);
     72 	unsigned long bytesPerFrame = numChannels * bytesPerSample;
     73 	
     74     waveFormatEx->wFormatTag = waveFormatTag;
     75 	waveFormatEx->nChannels = (WORD)numChannels;
     76 	waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
     77 	waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
     78 	waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
     79 	waveFormatEx->wBitsPerSample = bytesPerSample * 8;
     80 	waveFormatEx->cbSize = 0;
     81 }
     82 
     83 
     84 void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, 
     85 		int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
     86 		PaWinWaveFormatChannelMask channelMask )
     87 {
     88 	WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
     89     int bytesPerSample = Pa_GetSampleSize(sampleFormat);
     90 	unsigned long bytesPerFrame = numChannels * bytesPerSample;
     91     GUID guid;
     92 
     93 	waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
     94 	waveFormatEx->nChannels = (WORD)numChannels;
     95 	waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
     96 	waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
     97 	waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
     98 	waveFormatEx->wBitsPerSample = bytesPerSample * 8;
     99 	waveFormatEx->cbSize = 22;
    100 
    101 	*((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) =
    102 			waveFormatEx->wBitsPerSample;
    103 
    104 	*((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask;
    105 		
    106     guid = pawin_ksDataFormatSubtypeGuidBase;
    107     guid.Data1 = (USHORT)waveFormatTag;
    108     *((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
    109 }
    110 
    111 PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
    112 {
    113 	switch( numChannels ){
    114 		case 1:
    115 			return PAWIN_SPEAKER_MONO;
    116 		case 2:
    117 			return PAWIN_SPEAKER_STEREO; 
    118 		case 3:
    119             return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT;
    120 		case 4:
    121 			return PAWIN_SPEAKER_QUAD;
    122 		case 5:
    123             return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER;
    124 		case 6:
    125             /* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time:
    126                 http://msdn2.microsoft.com/en-us/library/aa474707.aspx
    127                We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND)
    128                because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND 
    129                results in a virtual mixdown placing the rear output in the 
    130                front _and_ rear speakers.
    131             */
    132 			return PAWIN_SPEAKER_5POINT1; 
    133         /* case 7: */
    134 		case 8:
    135             /* RoBi: PAWIN_SPEAKER_7POINT1_SURROUND fits normal surround sound setups better than PAWIN_SPEAKER_7POINT1, f.i. NVidia HDMI Audio
    136                output is silent on channels 5&6 with NVidia drivers, and channel 7&8 with Micrsoft HD Audio driver using PAWIN_SPEAKER_7POINT1. 
    137                With PAWIN_SPEAKER_7POINT1_SURROUND both setups work OK. */
    138 			return PAWIN_SPEAKER_7POINT1_SURROUND;
    139 	}
    140 
    141     /* Apparently some Audigy drivers will output silence 
    142        if the direct-out constant (0) is used. So this is not ideal.    
    143 
    144        RoBi 2012-12-19: Also, NVidia driver seem to output garbage instead. Again not very ideal.
    145     */
    146 	return  PAWIN_SPEAKER_DIRECTOUT;
    147 
    148     /* Note that Alec Rogers proposed the following as an alternate method to 
    149         generate the default channel mask, however it doesn't seem to be an improvement
    150         over the above, since some drivers will matrix outputs mapping to non-present
    151         speakers accross multiple physical speakers.
    152 
    153         if(nChannels==1) {
    154             pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER;
    155         }
    156         else {
    157             pwfFormat->dwChannelMask = 0;
    158             for(i=0; i<nChannels; i++)
    159                 pwfFormat->dwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1;
    160         }
    161     */
    162 }