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

patest_leftright.c (6538B)


      1 /** @file patest_leftright.c
      2 	@ingroup test_src
      3 	@brief Play different tone sine waves that 
      4 		alternate between left and right channel.
      5 
      6 	The low tone should be on the left channel.
      7 
      8 	@author Ross Bencina <rossb@audiomulch.com>
      9 	@author Phil Burk <philburk@softsynth.com>
     10 */
     11 /*
     12  * $Id$
     13  *
     14  * This program uses the PortAudio Portable Audio Library.
     15  * For more information see: http://www.portaudio.com
     16  * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
     17  *
     18  * Permission is hereby granted, free of charge, to any person obtaining
     19  * a copy of this software and associated documentation files
     20  * (the "Software"), to deal in the Software without restriction,
     21  * including without limitation the rights to use, copy, modify, merge,
     22  * publish, distribute, sublicense, and/or sell copies of the Software,
     23  * and to permit persons to whom the Software is furnished to do so,
     24  * subject to the following conditions:
     25  *
     26  * The above copyright notice and this permission notice shall be
     27  * included in all copies or substantial portions of the Software.
     28  *
     29  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     30  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     32  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
     33  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
     34  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     35  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     36  */
     37 
     38 /*
     39  * The text above constitutes the entire PortAudio license; however, 
     40  * the PortAudio community also makes the following non-binding requests:
     41  *
     42  * Any person wishing to distribute modifications to the Software is
     43  * requested to send the modifications to the original developer so that
     44  * they can be incorporated into the canonical version. It is also 
     45  * requested that these non-binding requests be included along with the 
     46  * license above.
     47  */
     48 
     49 #include <stdio.h>
     50 #include <math.h>
     51 #include "portaudio.h"
     52 
     53 #define NUM_SECONDS   (8)
     54 #define SAMPLE_RATE   (44100)
     55 #define FRAMES_PER_BUFFER  (512)
     56 #ifndef M_PI
     57 #define M_PI  (3.14159265)
     58 #endif
     59 #define TABLE_SIZE   (200)
     60 #define BALANCE_DELTA  (0.001)
     61 
     62 typedef struct
     63 {
     64     float sine[TABLE_SIZE];
     65     int left_phase;
     66     int right_phase;
     67     float targetBalance; // 0.0 = left, 1.0 = right
     68     float currentBalance;
     69 } paTestData;
     70 
     71 /* This routine will be called by the PortAudio engine when audio is needed.
     72 ** It may called at interrupt level on some machines so don't do anything
     73 ** that could mess up the system like calling malloc() or free().
     74 */
     75 static int patestCallback( const void *inputBuffer,
     76                            void *outputBuffer,
     77                            unsigned long framesPerBuffer,
     78                            const PaStreamCallbackTimeInfo* timeInfo,
     79                            PaStreamCallbackFlags statusFlags,
     80                            void *userData )
     81 {
     82     paTestData *data = (paTestData*)userData;
     83     float *out = (float*)outputBuffer;
     84     unsigned long i;
     85     int finished = 0;
     86     /* Prevent unused variable warnings. */
     87     (void) inputBuffer;
     88 
     89     for( i=0; i<framesPerBuffer; i++ )
     90     {
     91 		// Smoothly pan between left and right.
     92 		if( data->currentBalance < data->targetBalance )
     93 		{
     94 			data->currentBalance += BALANCE_DELTA;
     95 		}
     96 		else if( data->currentBalance > data->targetBalance )
     97 		{
     98 			data->currentBalance -= BALANCE_DELTA;
     99 		}
    100 		// Apply left/right balance.
    101         *out++ = data->sine[data->left_phase] * (1.0f - data->currentBalance);  /* left */
    102 		*out++ = data->sine[data->right_phase] * data->currentBalance;  /* right */
    103 		
    104         data->left_phase += 1;
    105         if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
    106         data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
    107         if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
    108     }
    109 
    110     return finished;
    111 }
    112 
    113 /*******************************************************************/
    114 int main(void);
    115 int main(void)
    116 {
    117     PaStream *stream;
    118     PaStreamParameters outputParameters;
    119     PaError err;
    120     paTestData data;
    121     int i;    
    122     printf("Play different tone sine waves that alternate between left and right channel.\n");
    123     printf("The low tone should be on the left channel.\n");
    124     
    125     /* initialise sinusoidal wavetable */
    126     for( i=0; i<TABLE_SIZE; i++ )
    127     {
    128         data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
    129     }
    130     data.left_phase = data.right_phase = 0;
    131     data.currentBalance = 0.0;
    132     data.targetBalance = 0.0;
    133 
    134     err = Pa_Initialize();
    135     if( err != paNoError ) goto error;
    136 
    137     outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
    138     if (outputParameters.device == paNoDevice) {
    139       fprintf(stderr,"Error: No default output device.\n");
    140       goto error;
    141     }
    142     outputParameters.channelCount = 2;       /* stereo output */
    143     outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
    144     outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
    145     outputParameters.hostApiSpecificStreamInfo = NULL;
    146 
    147     err = Pa_OpenStream( &stream,
    148                          NULL,                  /* No input. */
    149                          &outputParameters,     /* As above. */
    150                          SAMPLE_RATE,
    151                          FRAMES_PER_BUFFER,
    152                          paClipOff,      /* we won't output out of range samples so don't bother clipping them */
    153                          patestCallback,
    154                          &data );
    155     if( err != paNoError ) goto error;
    156     
    157     err = Pa_StartStream( stream );
    158     if( err != paNoError ) goto error;
    159     
    160     printf("Play for several seconds.\n");
    161     for( i=0; i<4; i++ )
    162 	{
    163 		printf("Hear low sound on left side.\n");
    164 		data.targetBalance = 0.01;
    165         Pa_Sleep( 1000 );
    166 		
    167 		printf("Hear high sound on right side.\n");
    168 		data.targetBalance = 0.99;
    169         Pa_Sleep( 1000 ); 
    170 	}
    171 
    172     err = Pa_StopStream( stream );
    173     if( err != paNoError ) goto error;
    174     err = Pa_CloseStream( stream );
    175     if( err != paNoError ) goto error;
    176     Pa_Terminate();
    177     printf("Test finished.\n");
    178     return err;
    179 error:
    180     Pa_Terminate();
    181     fprintf( stderr, "An error occured while using the portaudio stream\n" );
    182     fprintf( stderr, "Error number: %d\n", err );
    183     fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
    184     return err;
    185 }