SHARE
TWEET

playnotes.c

flarn2006 Mar 4th, 2012 62 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // playnotes.c - Plays a string of notes given on the command line.
  2. // Created by flarn2006 - http://flarn2006.blogspot.com/
  3. // Licensed under Creative Commons Attribution-ShareAlike 3.0 Unported
  4. // Requires libao (http://xiph.org/ao/) - Compile with "-lao"
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdint.h>
  9. #include <math.h>
  10. #include <string.h>
  11. #include <ao/ao.h>
  12. #define SAMPLE_RATE 44100
  13. #define NOTE_LENGTH 0.180
  14.  
  15. double tofreq(char note);
  16.  
  17. void play_note(ao_device *device, double freq, double duration)
  18. {
  19.         unsigned long i;
  20.         size_t length = SAMPLE_RATE * duration;
  21.         int16_t *audio = malloc(length*2);
  22.        
  23.         for (i=0; i<length; i++)
  24.         {
  25.                 double value = sin(i * 2 * M_PI * (freq / (double)SAMPLE_RATE));
  26.                 audio[i] = (int16_t)(value * 0x7FFF);
  27.         }
  28.        
  29.         ao_play(device, (char*)audio, length*2);
  30.        
  31.         free(audio);
  32. }
  33.  
  34. int main(int argc, char *argv[])
  35. {
  36.         ao_device *device;
  37.         ao_sample_format fmt;
  38.         double duration = NOTE_LENGTH;
  39.         double octave_mult = 1.0;
  40.  
  41.         if (argc == 2);  // do nothing
  42.         else if (argc == 3)
  43.         {
  44.                 sscanf(argv[2], "%lf", &duration);
  45.                 if (duration < 0)
  46.                 {
  47.                         printf("Note length can't be negative!\n");
  48.                         return 1;
  49.                 }
  50.         }
  51.         else
  52.         {
  53.                 printf("Usage: %s notes [length]\n", argv[0]);
  54.                 return 2;
  55.         }
  56.        
  57.         fmt.bits = 16;
  58.         fmt.rate = SAMPLE_RATE;
  59.         fmt.channels = 1;
  60.         fmt.byte_format = AO_FMT_NATIVE;
  61.         fmt.matrix = NULL;
  62.        
  63.         ao_initialize();
  64.        
  65.         device = ao_open_live(ao_default_driver_id(), &fmt, NULL);
  66.        
  67.         int i; for (i=0; i<strlen(argv[1]); i++)
  68.         {
  69.                 char ch = argv[1][i];
  70.                 switch (ch)
  71.                 {
  72.                         case '-': octave_mult *= 0.5; break;
  73.                         case '+': octave_mult *= 2.0; break;
  74.                         default: play_note(device, tofreq(ch) * octave_mult, duration);
  75.                 }
  76.         }
  77.        
  78.         ao_close(device);
  79.         ao_shutdown();
  80.        
  81.         return 0;
  82. }
  83.  
  84. double tofreq(char note)
  85. {
  86.         switch (note)
  87.         {
  88.                 case 'C': case 'c': return 261.63; break;
  89.                 case 'D': case 'd': return 293.66; break;
  90.                 case 'E': case 'e': return 329.63; break;
  91.                 case 'F': case 'f': return 349.23; break;
  92.                 case 'G': case 'g': return 392.00; break;
  93.                 case 'A': case 'a': return 440.00; break;
  94.                 case 'B': case 'b': return 493.88; break;
  95.                 default:  return 0.00;   break; //rest
  96.         }
  97. }
RAW Paste Data
Top