Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.02 KB | None | 0 0
  1. /*
  2.  * a.out <audiofile> <sampleskew>
  3.  *
  4.  * This program reads in a raw file (assuming 16bit PCM 44.1kHz mono), adjusts
  5.  * the sample rate, and writes the audio to pulseaudio.
  6.  */
  7.  
  8. #include <assert.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <math.h>
  13. #include <time.h>
  14. #include <pulse/simple.h>
  15. #include "libavcodec/avcodec.h"
  16.  
  17. #define LENGTH_MS 500       // how many milliseconds of speech to store
  18. #define RATE 44100      // the sampling rate
  19. #define FORMAT PA_SAMPLE_S16NE  // sample size: 8 or 16 bits
  20. #define CHANNELS 1      // 1 = mono 2 = stereo
  21. #define ANGLE_STEP_PER_SEC 15.0 // degrees per second
  22.  
  23. #define DEG2RAD( angle ) (((angle)/180.0)*3.14159265)
  24.  
  25. /* Globals */
  26. FILE* infile = 0;
  27. char* filename = 0;
  28. int rate_skew = 0; // Num samples to skew
  29. long file_len = 0;
  30. pa_simple* pulse_conn;
  31. pa_sample_spec spec;
  32. struct AVResampleContext* audio_cntx = 0;
  33. double angle = 0.0;
  34. double prev_time = 0.0;
  35.  
  36. /* this buffer holds the digitized audio */
  37. char in_buffer[(LENGTH_MS*RATE*16*CHANNELS)/8000];
  38. char out_buffer[ sizeof( in_buffer ) * 4];
  39.  
  40. /**/
  41. int calc_skew()
  42. {
  43.     // Calculate how much time has elapsed sinse the last call.
  44.     struct timeval now_tv;
  45.     gettimeofday( &now_tv, 0 );
  46.     double now = (double)now_tv.tv_sec + ((double)now_tv.tv_usec / 1000000.0);
  47.     double delta = 0.0;
  48.     if( prev_time )
  49.         delta = now - prev_time;
  50.     prev_time = now;
  51.  
  52.     // Calculate how much to increase the angle by.
  53.     angle += ANGLE_STEP_PER_SEC * delta; // 'delta' is normalized to seconds so this works.
  54.     if( angle >= 360.0 )
  55.         angle = angle - 360.0;
  56.  
  57.     return( rate_skew * sin( DEG2RAD(angle) ) );
  58. }
  59.  
  60. /**/
  61. void play_audio()
  62. {
  63.     size_t bytes_read = 0;
  64.     size_t total_bytes_read = 0;
  65.     // Loop through the file until all data is read.
  66.     for( ; !feof( infile ) && !ferror( infile ); )
  67.     {
  68.         // Read the next chunk of data from the file.
  69.         bytes_read = fread( in_buffer, 1, sizeof( in_buffer ), infile );
  70.         assert( !ferror( infile ) && "Error reading audio file!" );
  71.         total_bytes_read += bytes_read;
  72.  
  73.         // Resample audio.
  74.         int out_rate = RATE + calc_skew();
  75.         audio_cntx = av_resample_init( out_rate,    // out rate
  76.             RATE,   // in rate
  77.             16, // filter length
  78.             10, // phase count
  79.             0// linear FIR filter
  80.             1.0 );  // cutoff frequency
  81.         assert( audio_cntx && "Failed to create resampling context!" );
  82.  
  83.         int samples_consumed = 0;
  84.         int samples_output = av_resample( audio_cntx,
  85.             (short*)out_buffer,
  86.             (short*)in_buffer,
  87.             &samples_consumed,
  88.             bytes_read / 2,
  89.             sizeof( out_buffer ) / 2, // in samples
  90.             0 );
  91.         assert( samples_output > 0 && "Error calling av_resample()!" );
  92.  
  93.         av_resample_close( audio_cntx );
  94.  
  95.         // Play the processed samples.
  96.         pa_simple_write( pulse_conn,
  97.             out_buffer,
  98.             samples_output * 2,
  99.             0 );
  100.  
  101.         // Display progress text.
  102.         printf( "\rProgress: %2.1f%% Complete, Skew: %2.1f%%, Angle: %2.1f Degrees       ",
  103.             ((float)total_bytes_read/(float)file_len)*100.0,
  104.             ((float)(out_rate)/(float)RATE)*100.0,
  105.             angle );
  106.         fflush( stdout );
  107.     }
  108.     printf( "\nDone!\n" );
  109. }
  110.  
  111. /**/
  112. int main(int argc, char *argv[])
  113. {
  114.     assert( argc > 2 && "Please specify a file and skew!" );
  115.     filename = argv[1];
  116.     rate_skew = atoi( argv[2] );
  117.  
  118.     // Initialize ffmpeg resampling.
  119.     avcodec_init();
  120.  
  121.     // Open audio file.
  122.     infile = fopen( filename, "rb" );
  123.     assert( infile && "Error opening file!" );
  124.     fseek( infile, 0, SEEK_END );
  125.     file_len = ftell( infile );
  126.     fseek( infile, 0, SEEK_SET );
  127.  
  128.     // Open connection to pulse audio server.
  129.     spec.format = FORMAT;
  130.     spec.channels = CHANNELS;
  131.     spec.rate = RATE;
  132.     pulse_conn = pa_simple_new( NULL, // Use the default server.
  133.         "audio_skew_rate"// Our application's name.
  134.         PA_STREAM_PLAYBACK,
  135.         NULL,           // Use the default device.
  136.         "Music",        // Description of our stream.
  137.         &spec,          // Our sample format.
  138.         NULL,           // Use default channel map
  139.         NULL,           // Use default buffering attributes.
  140.         NULL );         // Ignore error code.
  141.  
  142.  
  143.     // Play audio.
  144.     play_audio();
  145.    
  146.     // Clean up
  147.     pa_simple_free( pulse_conn );
  148.     fclose( infile );
  149.  
  150.     return( 0 );
  151. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement