Ejemplo n.º 1
1
//*******************************************************************************
//*  audio_thread_fxn                                                          **
//*******************************************************************************
//*  Input Parameters:                                                         **
//*      void *envByRef    --  a pointer to an audio_thread_env structure      **
//*                            as defined in audio_thread.h                    **
//*                                                                            **
//*          envByRef.quit -- when quit != 0, thread will cleanup and exit     **
//*                                                                            **
//*  Return Value:                                                             **
//*      void *            --  AUDIO_THREAD_SUCCESS or AUDIO_THREAD_FAILURE as **
//*                            defined in audio_thread.h                       **
//*******************************************************************************
void *audio_thread_fxn( void *envByRef )
{

// Variables and definitions
// *************************

    // Thread parameters and return value
    audio_thread_env * envPtr = envByRef;                  // < see above >
    void             * status = AUDIO_THREAD_SUCCESS;      // < see above >

    // The levels of initialization for initMask
    #define     INPUT_ALSA_INITIALIZED      0x1
    #define     INPUT_BUFFER_ALLOCATED      0x2
    #define     OUTPUT_ALSA_INITIALIZED     0x4
    #define     OUTPUT_BUFFER_ALLOCATED     0x8
    #define     RECORD_BUFFER_ALLOCATED     0x10

    unsigned  int   initMask =  0x0;	// Used to only cleanup items that were init'd

    // Input and output driver variables
    snd_pcm_t	*pcm_capture_handle;
    snd_pcm_t	*pcm_output_handle;		// Handle for the PCM device
    snd_pcm_uframes_t exact_bufsize;		// bufsize is in frames.  Each frame is 4 bytes

    int   blksize = BLOCKSIZE;			// Raw input or output frame size in bytes
    int *outputBuffer = NULL;			// Output buffer for driver to read from
    int *inputBuffer = NULL;		// Input buffer for driver to read into

    int *recordBuffer = NULL;
    

// Thread Create Phase -- secure and initialize resources
// ******************************************************

    // Setup audio input device
    // ************************

    // Open an ALSA device channel for audio input
    exact_bufsize = blksize/BYTESPERFRAME;
    if( audio_io_setup( &pcm_capture_handle, SOUND_DEVICE_IN, SAMPLE_RATE, 
			SND_PCM_STREAM_CAPTURE, &exact_bufsize ) == AUDIO_FAILURE )
    {
        ERR( "Audio_input_setup failed in audio_thread_fxn\n\n" );
        status = AUDIO_THREAD_FAILURE;
        goto cleanup;
    }
    DBG( "exact_bufsize = %d\n", (int) exact_bufsize);

    // Record that input OSS device was opened in initialization bitmask
    initMask |= INPUT_ALSA_INITIALIZED;

    blksize = exact_bufsize*BYTESPERFRAME;
    // Create input buffer to read into from OSS input device
    if( ( inputBuffer = malloc( blksize * sizeof(int) ) ) == NULL )
    {
        ERR( "Failed to allocate memory for input block (%d)\n", blksize * sizeof(int) );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Allocated input audio buffer of size %d to address %p\n", blksize * sizeof(int), inputBuffer );

    // Record that the input buffer was allocated in initialization bitmask
    initMask |= INPUT_BUFFER_ALLOCATED;

    // Initialize audio output device
    // ******************************

    // Initialize the output ALSA device
    DBG( "pcm_output_handle before audio_output_setup = %d\n", (int) pcm_output_handle);
    exact_bufsize = blksize/BYTESPERFRAME;
    DBG( "Requesting bufsize = %d\n", (int) exact_bufsize);
    if( audio_io_setup( &pcm_output_handle, SOUND_DEVICE_OUT, SAMPLE_RATE, 
			SND_PCM_STREAM_PLAYBACK, &exact_bufsize) == AUDIO_FAILURE )
    {
        ERR( "audio_output_setup failed in audio_thread_fxn\n" );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	DBG( "pcm_output_handle after audio_output_setup = %d\n", (int) pcm_output_handle);
	DBG( "blksize = %d, exact_bufsize = %d\n", blksize, (int) exact_bufsize);
	blksize = exact_bufsize;

    // Record that input ALSA device was opened in initialization bitmask
    initMask |= OUTPUT_ALSA_INITIALIZED;

    // Create output buffer to write from into ALSA output device
    if( ( outputBuffer = malloc( blksize * sizeof(int) ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize * sizeof(int) );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Allocated output audio buffer of size %d to address %p\n", blksize * sizeof(int), outputBuffer );

    // Record that the output buffer was allocated in initialization bitmask
    initMask |= OUTPUT_BUFFER_ALLOCATED;

    long temp = (long)blksize * RECORDTIME;
    if( ( recordBuffer = malloc( temp * sizeof(int) ) ) == NULL )
    {
        ERR( "Failed to allocate memory for record block (%d)\n", temp * sizeof(int) );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Allocated record audio buffer of size %d to address %p\n", temp * sizeof(int), recordBuffer );

    // Record that the output buffer was allocated in initialization bitmask
    initMask |= RECORD_BUFFER_ALLOCATED;

// Thread Execute Phase -- perform I/O and processing
// **************************************************
    // Get things started by sending some silent buffers out.
    int i;
    memset(outputBuffer, 0, blksize * sizeof(int));		// Clear the buffers
    memset(inputBuffer, 0, blksize * sizeof(int));
    memset(recordBuffer, 0, temp * sizeof(int));
    for(i=0; i<5; i++) {
	while ((snd_pcm_readi(pcm_capture_handle, inputBuffer, 
		blksize/BYTESPERFRAME)) < 0) {
	    snd_pcm_prepare(pcm_capture_handle);
	    ERR( "<<< Pre Buffer Overrun >>>\n");
              }
        }    

    for(i=0; i<5; i++) {
	while ((snd_pcm_writei(pcm_output_handle, outputBuffer,
		exact_bufsize)) < 0) {
	    snd_pcm_prepare(pcm_output_handle);
	    ERR( "<<<Pre Buffer Underrun >>> \n");
	      }
	}

//
// Processing loop
//
    DBG( "Entering audio_thread_fxn processing loop\n" );

    int count = 0;
    while( !envPtr->quit )
    {
	// Read capture buffer from ALSA input device

        if( snd_pcm_readi(pcm_capture_handle, inputBuffer, blksize/BYTESPERFRAME) < 0 )
        {
	    snd_pcm_prepare(pcm_capture_handle);
	    ERR( "<<<<<<<<<<<<<<< Buffer Overrun >>>>>>>>>>>>>>>\n");
            ERR( "Error reading the data from file descriptor %d\n", (int) pcm_capture_handle );
            status = AUDIO_THREAD_FAILURE;
            goto  cleanup ;
        }
        memcpy(outputBuffer, inputBuffer, blksize * sizeof(int));
        if ( envPtr->replay == 1 ) {
            int i;
            for (i = 0; i < blksize; i++) {
                outputBuffer[i] += recordBuffer[((count%RECORDTIME)*blksize)+i];
            }
        } else {
            memcpy(&recordBuffer[((count%RECORDTIME)*blksize)], inputBuffer, blksize * sizeof(int));
        }
        
        // Write output buffer into ALSA output device
      while (snd_pcm_writei(pcm_output_handle, outputBuffer, blksize/BYTESPERFRAME) < 0) {
        snd_pcm_prepare(pcm_output_handle);
        ERR( "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n");
        status = AUDIO_THREAD_FAILURE;
        goto cleanup;
      }
	DBG("%d, ", count);
        count++;
    }
    DBG("\n");

    DBG( "Exited audio_thread_fxn processing loop\n" );


// Thread Delete Phase -- free up resources allocated by this file
// ***************************************************************

cleanup:

    DBG( "Starting audio thread cleanup to return resources to system\n" );

    // Close the audio drivers
    // ***********************
    //  - Uses the initMask to only free resources that were allocated.
    //  - Nothing to be done for mixer device, as it was closed after init.

    // Close input OSS device
    if( initMask & INPUT_ALSA_INITIALIZED )
        if( audio_io_cleanup( pcm_capture_handle ) != AUDIO_SUCCESS )
        {
            ERR( "audio_input_cleanup() failed for file descriptor %d\n", (int) pcm_capture_handle );
            status = AUDIO_THREAD_FAILURE;
        }

    // Close output ALSA device
    if( initMask & OUTPUT_ALSA_INITIALIZED )
        if( audio_io_cleanup( pcm_output_handle ) != AUDIO_SUCCESS )
        {
            ERR( "audio_output_cleanup() failed for file descriptor %d\n", (int)pcm_output_handle );
            status = AUDIO_THREAD_FAILURE;
        }

    // Free allocated buffers
    // **********************

    // Free input buffer
    if( initMask & INPUT_BUFFER_ALLOCATED )
    {
        DBG( "Freeing audio input buffer at location %p\n", inputBuffer );
        free( inputBuffer );
        DBG( "Freed audio input buffer at location %p\n", inputBuffer );
    }

    // Free output buffer
    if( initMask & OUTPUT_BUFFER_ALLOCATED )
    {
        free( outputBuffer );
        DBG( "Freed audio output buffer at location %p\n", outputBuffer );
    }

    // Free record buffer
    if( initMask & RECORD_BUFFER_ALLOCATED)
    {
        free( recordBuffer );
        DBG( "Freed audio record buffer at location %p\n", recordBuffer );
    }

    // Return from audio_thread_fxn function
    // *************************************
	
    // Return the status at exit of the thread's execution
    DBG( "Audio thread cleanup complete. Exiting audio_thread_fxn\n" );
    return status;
}
Ejemplo n.º 2
0
void *dsp_thread_start( void *envByRef )
{	
	// DSP Thread Parameters
	dsp_thread_env * envPtr = envByRef; // < see above >
    void * status = DSP_THREAD_SUCCESS; // < see above >
    
    // Define audio paramters
    audio_params ap = {0}; // initialize ap
    ap.initMask = 0x0; // set init mask to 0x0
    ap.exact_bufsize = BLOCKSIZE/BYTESPERFRAME;// set buffer size
    ap.pcm_capture_handle = NULL;
    ap.pcm_output_handle = NULL;
    ap.blksize = BLOCKSIZE; // set block size
    ap.right_gain = RIGHT_GAIN; // set left channel gain
    ap.left_gain = LEFT_GAIN; // set right channel gain
    ap.sample_rate = SAMPLE_RATE; // set sampling rate
    ap.inputBuffer = NULL;
    ap.outputBuffer = NULL;
    
    // Setup audio codec and I/O buffers
    if( audio_io_setup( (void *) &ap ) == AUDIO_FAILURE )
    {
        ERR( "Audio_input_setup failed in dsp_thread_start\n\n" );
        status = DSP_THREAD_FAILURE;
    }
    
    // Perform I/O and Processing
	ioProcessing(envByRef,&ap);

    // Cleanup: Free up resources
    if( audio_io_cleanup( (void *) &ap ) == AUDIO_FAILURE )
    {
        ERR( "Audio_io_cleanup failed in dsp_thread_start\n\n" );
        status = DSP_THREAD_FAILURE;
    }
    
    envPtr->done = 1;
    
    // Finish
    return status;
}
//*******************************************************************************
//*  audio_thread_fxn                                                          **
//*******************************************************************************
//*  Input Parameters:                                                         **
//*      void *envByRef    --  a pointer to an audio_thread_env structure      **
//*                            as defined in audio_thread.h                    **
//*                                                                            **
//*          envByRef.quit -- when quit != 0, thread will cleanup and exit     **
//*                                                                            **
//*  Return Value:                                                             **
//*      void *            --  AUDIO_THREAD_SUCCESS or AUDIO_THREAD_FAILURE as **
//*                            defined in audio_thread.h                       **
//*******************************************************************************
void *audio_thread_fxn( void *envByRef )
{

// Variables and definitions
// *************************

    // Thread parameters and return value
    audio_thread_env * envPtr = envByRef;                  // < see above >
    void             * status = AUDIO_THREAD_SUCCESS;      // < see above >

    // The levels of initialization for initMask
    #define     INPUT_ALSA_INITIALIZED      0x1
    #define     INPUT_BUFFER_ALLOCATED      0x2
    #define     OUTPUT_FILE_OPENED          0x4

    unsigned  int   initMask =  0x0;		// Used to only cleanup items that were init'd

    // Input and output driver variables
    snd_pcm_uframes_t exact_bufsize;
    snd_pcm_t	*pcm_capture_handle;

    FILE          * outfile = NULL;	// Output file pointer (i.e. handle)
    int   blksize = BLOCKSIZE;		// Raw input or output frame size
    char *inputBuffer = NULL;		// Input buffer for driver to read into

// Thread Create Phase -- secure and initialize resources
// ******************************************************

    // Setup audio input device
    // ************************

    // Open an ALSA device channel for audio input
    exact_bufsize = blksize/BYTESPERFRAME;

    if( audio_io_setup( &pcm_capture_handle, SOUND_DEVICE, SAMPLE_RATE, 
			SND_PCM_STREAM_CAPTURE, &exact_bufsize ) == AUDIO_FAILURE )
    {
        ERR( "Audio_input_setup failed in audio_thread_fxn\n\n" );
        status = AUDIO_THREAD_FAILURE;
        goto cleanup;
    }
    DBG( "exact_bufsize = %d\n", (int) exact_bufsize);

    // Record that input OSS device was opened in initialization bitmask
    initMask |= INPUT_ALSA_INITIALIZED;

    blksize = exact_bufsize*BYTESPERFRAME;
    // Create input buffer to read into from OSS input device
    if( ( inputBuffer = malloc( blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for input block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Allocated input audio buffer of size %d to address %p\n", blksize, inputBuffer );

    // Record that the input buffer was allocated in initialization bitmask
    initMask |= INPUT_BUFFER_ALLOCATED;

    // Open audio output file
    // **********************

    // Open a file for record
    outfile = fopen(OUTFILE, "w");

    if( outfile == NULL )
    {
        ERR( "Failed to open file %s\n", OUTFILE );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Opened file %s with FILE pointer = %p\n", OUTFILE, outfile );

    // Record that input OSS device was opened in initialization bitmask
    initMask |= OUTPUT_FILE_OPENED;


// Thread Execute Phase -- perform I/O and processing
// **************************************************

    // Processing loop
    DBG( "Entering audio_thread_fxn processing loop\n" );

    while( !envPtr->quit )
    {
        // Read capture buffer from ALSA input device

        if( snd_pcm_readi(pcm_capture_handle, inputBuffer, blksize/BYTESPERFRAME) < 0 )
        {
	    snd_pcm_prepare(pcm_capture_handle);
	    ERR( "<<<<<<<<<<<<<<< Buffer Overrun >>>>>>>>>>>>>>>\n");
            ERR( "Error reading the data from file descriptor %d\n", (int) pcm_capture_handle );
            status = AUDIO_THREAD_FAILURE;
            goto  cleanup ;
        }

        if( fwrite( inputBuffer, sizeof( char ), blksize, outfile ) < blksize )
        {
            ERR( "Error writing the data to FILE pointer %p\n", outfile );
            status = AUDIO_THREAD_FAILURE;
            goto cleanup;
        }
    }

    DBG( "Exited audio_thread_fxn processing loop\n" );


// Thread Delete Phase -- free up resources allocated by this file
// ***************************************************************

cleanup:

    DBG( "Starting audio thread cleanup to return resources to system\n" );

    // Close the audio drivers
    // ***********************
    //  - Uses the initMask to only free resources that were allocated.
    //  - Nothing to be done for mixer device, as it was closed after init.

    // Close input OSS device
    if( initMask & INPUT_ALSA_INITIALIZED )
        if( audio_io_cleanup( pcm_capture_handle ) != AUDIO_SUCCESS )
        {
            ERR( "audio_input_cleanup() failed for file descriptor %d\n", (int) pcm_capture_handle );
            status = AUDIO_THREAD_FAILURE;
        }

    // Close output file
    if( initMask & OUTPUT_FILE_OPENED )
    {
        DBG( "Closing output file at FILE ptr %p\n", outfile );
        fclose( outfile );
    }

    // Free allocated buffers
    // **********************

    // Free input buffer
    if( initMask & INPUT_BUFFER_ALLOCATED )
    {
        DBG( "Freeing audio input buffer at location %p\n", inputBuffer );
        free( inputBuffer );
        DBG( "Freed audio input buffer at location %p\n", inputBuffer );
    }

    // Return from audio_thread_fxn function
    // *************************************

    // Return the status at exit of the thread's execution
    DBG( "Audio thread cleanup complete. Exiting audio_thread_fxn\n" );
    return status;
}
Ejemplo n.º 4
0
//*******************************************************************************
//*  audio_thread_fxn                                                          **
//*******************************************************************************
//*  Input Parameters:                                                         **
//*      void *envByRef    --  a pointer to an audio_thread_env structure      **
//*                            as defined in audio_thread.h                    **
//*                                                                            **
//*          envByRef.quit -- when quit != 0, thread will cleanup and exit     **
//*                                                                            **
//*  Return Value:                                                             **
//*      void *            --  AUDIO_THREAD_SUCCESS or AUDIO_THREAD_FAILURE as **
//*                            defined in audio_thread.h                       **
//*******************************************************************************
void *audio_thread_fxn( void *envByRef )
{

// Variables and definitions
// *************************

    // Thread parameters and return value
    audio_thread_env * envPtr = envByRef;                  // < see above >
    void             * status = AUDIO_THREAD_SUCCESS;      // < see above >
    // The levels of initialization for initMask

    #define     INPUT_ALSA_INITIALIZED      0x1
    #define     INPUT_BUFFER_ALLOCATED      0x2
    #define     OUTPUT_ALSA_INITIALIZED     0x4
    #define     OUTPUT_BUFFER_ALLOCATED     0x8

    unsigned  int   initMask =  0x0;	// Used to only cleanup items that were init'd

    // Input and output driver variables
    //FILE	* inputFile = NULL;		// Input file pointer (i.e. handle)
    snd_pcm_t	*pcm_output_handle;
    snd_pcm_t	*pcm_capture_handle;		// Handle for the PCM device
    snd_pcm_uframes_t exact_bufsize;		// bufsize is in frames.  Each frame is 4 bytes

    int   blksize = BLOCKSIZE;			// Raw input or output frame size in bytes
    char *outputBuffer = NULL;
    char *outputBuffer2 = NULL;			// Output buffer for driver to read from
	char *playingBuffer = NULL;
// Thread Create Phase -- secure and initialize resources
// ******************************************************

    // Setup audio input device
    // ************************
    // Open an ALSA device channel for audio input
    exact_bufsize = blksize/BYTESPERFRAME;

    if( audio_io_setup( &pcm_capture_handle, SOUND_DEVICE, SAMPLE_RATE, 
			SND_PCM_STREAM_CAPTURE, &exact_bufsize ) == AUDIO_FAILURE )
    {
        ERR( "Audio_input_setup failed in audio_thread_fxn\n\n" );
        status = AUDIO_THREAD_FAILURE;
        goto cleanup;
    }
    DBG( "exact_bufsize = %d\n", (int) exact_bufsize);

    // Record that input OSS device was opened in initialization bitmask
    initMask |= INPUT_ALSA_INITIALIZED;

    blksize = exact_bufsize*BYTESPERFRAME;

    // Initialize audio output device
    // ******************************
    // Initialize the output ALSA device
    DBG( "pcm_output_handle before audio_output_setup = %d\n", (int) pcm_output_handle);
    exact_bufsize = blksize/BYTESPERFRAME;
    DBG( "Requesting bufsize = %d\n", (int) exact_bufsize);
    if( audio_io_setup( &pcm_output_handle, OUT_SOUND_DEVICE, SAMPLE_RATE, 
			SND_PCM_STREAM_PLAYBACK, &exact_bufsize) == AUDIO_FAILURE )
    {
        ERR( "audio_output_setup failed in audio_thread_fxn\n" );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	blksize = exact_bufsize;
	DBG( "pcm_output_handle after audio_output_setup = %d\n", (int) pcm_output_handle);
	DBG( "blksize = %d, exact_bufsize = %d\n", blksize, (int) exact_bufsize);

    // Record that input ALSA device was opened in initialization bitmask
    initMask |= OUTPUT_ALSA_INITIALIZED;

    // Create output buffer to write from into ALSA output device
    if( ( outputBuffer = malloc( blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	// Create 5 seconds of output buffer to circularly update
    if( ( outputBuffer2 = malloc( 500*blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	// This adds the two audio files together for play when enter is pressed
    if( ( playingBuffer = malloc( 500*blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Allocated output audio buffer of size %d to address %p\n", blksize, outputBuffer );

    // Record that the output buffer was allocated in initialization bitmask
    initMask |= OUTPUT_BUFFER_ALLOCATED;


// Thread Execute Phase -- perform I/O and processing
// **************************************************
    // Get things started by sending some silent buffers out.
    int i;

    memset(outputBuffer, 0, blksize);		// Clear the buffer
    memset(outputBuffer2, 0, blksize);		// Clear the buffer
    memset(playingBuffer, 0, blksize);		// Clear the buffer
    for(i=0; i<4; i++) {
	snd_pcm_readi(pcm_capture_handle, outputBuffer, blksize/BYTESPERFRAME);
	if ((snd_pcm_writei(pcm_output_handle, outputBuffer,
		exact_bufsize)) < 0) {
	    snd_pcm_prepare(pcm_output_handle);
	    ERR( "<<<Pre Buffer Underrun >>> \n");
	      }
	}


//
// Processing loop
//
    DBG( "Entering audio_thread_fxn processing loop\n" );

    int count = 0;			//count for the specific audio frame being played
	int count2 = 0;			//count to 500 to keep track of circular loop
	int flag = 0;			//goes high to indicate that 500 frames are captured and ready to be played back
	int playaudiocheck = 1; //goes high to indicate that 500 frames have been played and are ready for capture and play again
    while( !envPtr->quit )
    {

        // Read capture buffer from ALSA input device

        if( snd_pcm_readi(pcm_capture_handle, outputBuffer, blksize/BYTESPERFRAME) < 0 )
        {
	    snd_pcm_prepare(pcm_capture_handle);
        }

        // Write output buffer into ALSA output device
		if(!audiocaller || !flag){
			//If not playing last five seconds of audio or the buffer isn't filled to the 5 second capacity, then we want to continue to play audio regularly
        	if (snd_pcm_writei(pcm_output_handle, outputBuffer, blksize/BYTESPERFRAME) < 0) {
            	snd_pcm_prepare(pcm_output_handle);
	    		// Send out an extra blank buffer if there is an underrun and try again.
	    memset(outputBuffer, 0, blksize);		// Clear the buffer
	    snd_pcm_writei(pcm_output_handle, outputBuffer, exact_bufsize);
      		}
		}

		//Now we want to check to see if the buffer is full and the audio needs to be played back as well as if the audio has finished playing back
		if(audiocaller && (count2 == 499) && playaudiocheck){
		// This will determine that we are playing audio from this point as well we will say not to come back into this loop until the audio has been played and set count2 back to 0 for playing from the beginning
			count2 = 0;
			flag = 1;
			playaudiocheck = 0;
		}

		//Now we will play audio only if the flag says that we have a full buffer
		if(audiocaller && flag){
		//We have to add the signals from what sound is currently happening to the sounds that happened over the last 5 seconds together and then have them playback byter for byte
		for(i=0; i < blksize; i++){
			playingBuffer[i] = outputBuffer2[(count2*blksize)+i] + outputBuffer[i];
		}
		
		//When the audio has been formed it them plays back through the speakers with a snd_pcm_writei call for playingBuffer
		if (snd_pcm_writei(pcm_output_handle, playingBuffer, blksize/BYTESPERFRAME) < 0){ 
		   	snd_pcm_prepare(pcm_output_handle);
		    // Send out an extra blank buffer if there is an underrun and try again.
	        memset(playingBuffer, 0, blksize);		// Clear the buffer
	        snd_pcm_writei(pcm_output_handle, playingBuffer, blksize/BYTESPERFRAME);
        }
		//We now need to detect whether or not the buffer has come to an end and if it has we need to let the program know that we don't want to continue playing both audios together as well as let the buffer know it can be recalled to play again
		if(count2 > 498){
			audiocaller = 0;
			playaudiocheck = 1;
			flag = 0;
		}

}
	//Copies the recorded audio into the new buffer at the specified index
	memcpy(outputBuffer2 + (count2*blksize), outputBuffer, blksize);
	count++;
	count2++;
	count2 = count2 % 500;

	//DBG("%d, ", count++);
    }
    DBG("\n");

    DBG( "Exited audio_thread_fxn processing loop\n" );


// Thread Delete Phase -- free up resources allocated by this file
// ***************************************************************

cleanup:

    DBG( "Starting audio thread cleanup to return resources to system\n" );


    // Close output ALSA device
    if( initMask & OUTPUT_ALSA_INITIALIZED )
        if( audio_io_cleanup( pcm_output_handle ) != AUDIO_SUCCESS )
        {
            ERR( "audio_output_cleanup() failed for file descriptor %d\n", (int)pcm_output_handle );
            status = AUDIO_THREAD_FAILURE;
        }

    // Free allocated buffers
    // **********************

    // Free output buffer
    if( initMask & OUTPUT_BUFFER_ALLOCATED )
    {
        free( outputBuffer );
		free( outputBuffer2 );
		free( playingBuffer );
        DBG( "Freed audio output buffer at location %p\n", outputBuffer );
    }

    // Return from audio_thread_fxn function
    // *************************************
	
    // Return the status at exit of the thread's execution
    DBG( "Audio thread cleanup complete. Exiting audio_thread_fxn\n" );
    return status;
}
//*******************************************************************************
//*  audio_thread_fxn                                                          **
//*******************************************************************************
//*  Input Parameters:                                                         **
//*      void *envByRef    --  a pointer to an audio_thread_env structure      **
//*                            as defined in audio_thread.h                    **
//*                                                                            **
//*          envByRef.quit -- when quit != 0, thread will cleanup and exit     **
//*                                                                            **
//*  Return Value:                                                             **
//*      void *            --  AUDIO_THREAD_SUCCESS or AUDIO_THREAD_FAILURE as **
//*                            defined in audio_thread.h                       **
//*******************************************************************************
void *audio_thread_fxn( void *envByRef )
{

// Variables and definitions
// *************************

    // Thread parameters and return value
    audio_thread_env * envPtr = envByRef;                  // < see above >
    void             * status = AUDIO_THREAD_SUCCESS;      // < see above >

    // The levels of initialization for initMask
    #define     INPUT_FILE_OPENED           0x1
    #define     OUTPUT_ALSA_INITIALIZED     0x4
    #define     OUTPUT_BUFFER_ALLOCATED     0x8

            unsigned  int   initMask =  0x0;	// Used to only cleanup items that were init'd

    // Input and output driver variables
    FILE	* inputFile = NULL;		// Input file pointer (i.e. handle)
    snd_pcm_t	*pcm_output_handle;		// Handle for the PCM device
    snd_pcm_uframes_t exact_bufsize;		// bufsize is in frames.  Each frame is 4 bytes

    int   blksize = BLOCKSIZE;			// Raw input or output frame size in bytes
    char *outputBuffer = NULL;			// Output buffer for driver to read from

// Thread Create Phase -- secure and initialize resources
// ******************************************************

    // Open input file
    // ************************
	
    inputFile = fopen( INPUTFILE, "r" );

    if( inputFile == NULL )
    {
        ERR( "Failed to open file %s\n", INPUTFILE );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
    DBG( "Opened %s.\n", INPUTFILE);

    // Record that input file was opened in initialization bitmask
    initMask |= INPUT_FILE_OPENED;

    // Initialize audio output device
    // ******************************

    // Initialize the output ALSA device
    DBG( "pcm_output_handle before audio_output_setup = %d\n", (int) pcm_output_handle);
    exact_bufsize = blksize/BYTESPERFRAME;
    DBG( "Requesting bufsize = %d\n", (int) exact_bufsize);
    if( audio_io_setup( &pcm_output_handle, SOUND_DEVICE, SAMPLE_RATE, 
			SND_PCM_STREAM_PLAYBACK, &exact_bufsize) == AUDIO_FAILURE )
    {
        ERR( "audio_output_setup failed in audio_thread_fxn\n" );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }
	DBG( "pcm_output_handle after audio_output_setup = %d\n", (int) pcm_output_handle);
	DBG( "blksize = %d, exact_bufsize = %d\n", blksize, (int) exact_bufsize);
	blksize = exact_bufsize;

    // Record that input ALSA device was opened in initialization bitmask
    initMask |= OUTPUT_ALSA_INITIALIZED;

    // Create output buffer to write from into ALSA output device
    if( ( outputBuffer = malloc( blksize ) ) == NULL )
    {
        ERR( "Failed to allocate memory for output block (%d)\n", blksize );
        status = AUDIO_THREAD_FAILURE;
        goto  cleanup ;
    }

    DBG( "Allocated output audio buffer of size %d to address %p\n", blksize, outputBuffer );

    // Record that the output buffer was allocated in initialization bitmask
    initMask |= OUTPUT_BUFFER_ALLOCATED;


// Thread Execute Phase -- perform I/O and processing
// **************************************************
    // Get things started by sending some silent buffers out.
    int i;
    memset(outputBuffer, 0, blksize);		// Clear the buffer
    for(i=0; i<2; i++) {
	while ((snd_pcm_writei(pcm_output_handle, outputBuffer,
		exact_bufsize)) < 0) {
	    snd_pcm_prepare(pcm_output_handle);
	    ERR( "<<<Pre Buffer Underrun >>> \n");
	      }
	}
//
// Processing loop
//
    DBG( "Entering audio_thread_fxn processing loop\n" );

    int count = 0;
    while( !envPtr->quit )
    {
        // Read buffer from audio file
        if ((blksize = fread(outputBuffer, sizeof(char), blksize, inputFile)) == 0 )
        {
            DBG( "Reached end of file from FILE ptr %p\n", inputFile );
            goto  cleanup ;
        }

        // Write output buffer into ALSA output device
      while (snd_pcm_writei(pcm_output_handle, outputBuffer, blksize/BYTESPERFRAME) < 0) {
        snd_pcm_prepare(pcm_output_handle);
        ERR( "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n");
//        status = AUDIO_THREAD_FAILURE;
//        goto cleanup;
	// Send out an extra blank buffer if there is an underrun and try again.
	    memset(outputBuffer, 0, blksize);		// Clear the buffer
	    snd_pcm_writei(pcm_output_handle, outputBuffer, exact_bufsize);
      }
	DBG("%d, ", count++);
    }
    DBG("\n");

    DBG( "Exited audio_thread_fxn processing loop\n" );


// Thread Delete Phase -- free up resources allocated by this file
// ***************************************************************

cleanup:

    DBG( "Starting audio thread cleanup to return resources to system\n" );

    // Close the audio drivers
    // ***********************
    //  - Uses the initMask to only free resources that were allocated.
    //  - Nothing to be done for mixer device, as it was closed after init.

    // Close input file
    if( initMask & INPUT_FILE_OPENED )
    {
        DBG( "Closing FILE ptr %p\n", inputFile );
        fclose( inputFile );
    }

    // Close output ALSA device
    if( initMask & OUTPUT_ALSA_INITIALIZED )
        if( audio_io_cleanup( pcm_output_handle ) != AUDIO_SUCCESS )
        {
            ERR( "audio_output_cleanup() failed for file descriptor %d\n", (int)pcm_output_handle );
            status = AUDIO_THREAD_FAILURE;
        }

    // Free allocated buffers
    // **********************

    // Free output buffer
    if( initMask & OUTPUT_BUFFER_ALLOCATED )
    {
        free( outputBuffer );
        DBG( "Freed audio output buffer at location %p\n", outputBuffer );
    }

    // Return from audio_thread_fxn function
    // *************************************
	
    // Return the status at exit of the thread's execution
    DBG( "Audio thread cleanup complete. Exiting audio_thread_fxn\n" );
    return status;
}