Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

vumeter.c 3.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * vumeter.c:
  3. * Simple VU meter
  4. *
  5. * Heres the theory:
  6. * We will sample at 4000 samples/sec and put the data into a
  7. * low-pass filter with a depth of 1000 samples. This will give
  8. * us 1/4 a second of lag on the signal, but I think it might
  9. * produce a more pleasing output.
  10. *
  11. * The input of the microphone should be at mid-pont with no
  12. * sound input, but we might have to sample that too, to get
  13. * our reference zero...
  14. *
  15. * Copyright (c) 2013 Gordon Henderson
  16. ***********************************************************************
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <sys/time.h>
  21. #include <wiringPi.h>
  22. #include <gertboard.h>
  23. #ifndef TRUE
  24. #define TRUE (1==1)
  25. #define FALSE (!TRUE)
  26. #endif
  27. #define B_SIZE 1000
  28. #define S_SIZE 128
  29. static int buffer [B_SIZE] ;
  30. static int bPtr = 0 ;
  31. /*
  32. * ledPercent:
  33. * Output the given value as a percentage on the LEDs
  34. *********************************************************************************
  35. */
  36. static void ledPercent (int percent)
  37. {
  38. unsigned int output = 0 ;
  39. if (percent > 11) output |= 0x01 ;
  40. if (percent > 22) output |= 0x02 ;
  41. if (percent > 33) output |= 0x04 ;
  42. if (percent > 44) output |= 0x08 ;
  43. if (percent > 55) output |= 0x10 ;
  44. if (percent > 66) output |= 0x20 ;
  45. if (percent > 77) output |= 0x40 ;
  46. if (percent > 88) output |= 0x80 ;
  47. digitalWriteByte (output) ;
  48. }
  49. static unsigned int tPeriod, tNextSampleTime ;
  50. /*
  51. * sample:
  52. * Get a sample from the Gertboard. If not enough time has elapsed
  53. * since the last sample, then wait...
  54. *********************************************************************************
  55. */
  56. static void sample (void)
  57. {
  58. unsigned int tFuture ;
  59. // Calculate the future sample time
  60. tFuture = tPeriod + tNextSampleTime ;
  61. // Wait until the next sample time
  62. while (micros () < tNextSampleTime)
  63. ;
  64. buffer [bPtr] = gertboardAnalogRead (0) ;
  65. tNextSampleTime = tFuture ;
  66. }
  67. int main ()
  68. {
  69. int quietLevel, min, max ;
  70. int i, sum ;
  71. unsigned int tStart, tEnd ;
  72. printf ("\n") ;
  73. printf ("Gertboard demo: VU Meter\n") ;
  74. printf ("========================\n") ;
  75. wiringPiSetup () ;
  76. gertboardSPISetup () ;
  77. ledPercent (0) ;
  78. for (i = 0 ; i < 8 ; ++i)
  79. pinMode (i, OUTPUT) ;
  80. for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr)
  81. buffer [bPtr] = 99 ;
  82. tPeriod = 1000000 / 1000 ;
  83. printf ("Shhhh.... ") ; fflush (stdout) ;
  84. delay (1000) ;
  85. printf ("Sampling quiet... ") ; fflush (stdout) ;
  86. tStart = micros () ;
  87. tNextSampleTime = micros () ;
  88. for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr)
  89. sample () ;
  90. tEnd = micros () ;
  91. quietLevel = 0 ;
  92. max = 0 ;
  93. min = 1024 ;
  94. for (i = 0 ; i < B_SIZE ; ++i)
  95. {
  96. quietLevel += buffer [i] ;
  97. if (buffer [i] > max) max = buffer [i] ;
  98. if (buffer [i] < min) min = buffer [i] ;
  99. }
  100. quietLevel /= B_SIZE ;
  101. printf ("Done. Quiet level is: %d [%d:%d] [%d:%d]\n", quietLevel, min, max, quietLevel - min, max - quietLevel) ;
  102. printf ("Time taken for %d reads: %duS\n", B_SIZE, tEnd - tStart) ;
  103. for (bPtr = 0 ;;)
  104. {
  105. sample () ;
  106. sum = 0 ;
  107. for (i = 0 ; i < S_SIZE ; ++i)
  108. sum += buffer [i] ;
  109. sum /= S_SIZE ;
  110. sum = abs (quietLevel - sum) ;
  111. sum = (sum * 1000) / quietLevel ;
  112. ledPercent (sum) ;
  113. if (++bPtr > S_SIZE)
  114. bPtr = 0 ;
  115. }
  116. return 0 ;
  117. }