Advertisement
anmipo

NipkowTester

Nov 12th, 2011
1,718
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 7.77 KB | None | 0 0
  1. package com.anmipo.nipkow;
  2.  
  3. import java.io.BufferedOutputStream;
  4. import java.io.ByteArrayInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7.  
  8. import javax.sound.sampled.AudioFileFormat;
  9. import javax.sound.sampled.AudioFormat;
  10. import javax.sound.sampled.AudioInputStream;
  11. import javax.sound.sampled.AudioSystem;
  12. import javax.sound.sampled.Clip;
  13. import javax.sound.sampled.LineUnavailableException;
  14.  
  15. import com.sun.media.sound.WaveFileWriter;
  16.  
  17. public class NipkowTester {
  18.     //display resolution
  19.     public static final int ROWS = 32;
  20.     public static final int COLS = 22;
  21.     //frames (disk rotations) per second
  22.     public static final float FPS = 12.5f;
  23.     //clip duration
  24.     public static final int PLAY_DURATION_SECONDS = 10 * 60;
  25.        
  26.     //image data (scanned left-to-right, top-to-bottom)
  27.     //values denote brightness (0 - min, 9 - max)
  28.     public static final byte[] IMAGE = new byte[] {
  29.         //      5          10         15         20
  30.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //01
  31.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //02
  32.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //03
  33.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //04
  34.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //05
  35.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //06
  36.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,0,0,0,0, 0,0, //07
  37.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,0,0,0,0, 0,0, //08
  38.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,0,0,0,0, 0,0, //09
  39.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,0,0,0,0, 0,0, //10
  40.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //11
  41.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //12
  42.         0,0,0,9,9, 9,9,9,9,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //13
  43.         0,0,0,9,9, 9,9,9,9,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //14
  44.         0,0,0,9,9, 9,9,9,9,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //15
  45.         0,0,0,9,9, 9,9,9,9,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //16
  46.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //17
  47.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //18
  48.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //19
  49.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //20
  50.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //21
  51.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //22
  52.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //23
  53.         0,0,0,9,9, 0,0,0,0,9, 9,0,0,0,0, 0,9,9,0,0, 0,0, //24
  54.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //25
  55.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //26
  56.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //27
  57.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //28
  58.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //29
  59.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //30
  60.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //31
  61.         0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0, //32
  62.     };
  63.  
  64.     //sound sampling frequency
  65.     public static final int SAMPLE_RATE = 44100; //Hz
  66.     //career sound wave frequency to be modulated by pixel data
  67.     public static final int CAREER_FREQUENCY = 22050; //Hz
  68.     //each sound sample is multiplied by this number
  69.     public static final int VOLUME = 13;
  70.     //output audio format
  71.     public static final AudioFormat AUDIO_FORMAT =
  72.         new AudioFormat(
  73.                 SAMPLE_RATE,  //sample rate
  74.                 8,        //sample size in bits
  75.                 1,        //number of channels
  76.                 true,     //signed
  77.                 false);   //bigEndian
  78.    
  79.    
  80.     public static void main(String[] args) {
  81.         try {
  82.             byte[] samples = buildFrame(IMAGE, ROWS, COLS, FPS);
  83.             //saveToWav(samples, "d://temp//nipkov.wav");
  84.             playFrame(samples, (int)(PLAY_DURATION_SECONDS * FPS));
  85.         } catch (Exception e) {
  86.             e.printStackTrace();
  87.         }
  88.     }
  89.  
  90.     /**
  91.      * Constructs a sequence of raw audio samples representing the given image.
  92.      * @param image     the image to convert
  93.      * @param rows      vertical image size
  94.      * @param cols      horizontal image size
  95.      * @param fps       desired output frame rate
  96.      * @return array of raw audio samples in {@link #AUDIO_FORMAT} format
  97.      */
  98.     protected static byte[] buildFrame(byte[] image, int rows, int cols, float fps) {
  99.         if (image.length != (rows * cols))
  100.             throw new java.lang.IllegalArgumentException(
  101.                     String.format("The image is not %d by %d", rows, cols));
  102.        
  103.         float frameDuration = 1/fps; //seconds per frame
  104.         float pixelDuration = frameDuration / (cols * rows); //seconds per pixel
  105.         //number of sound samples per pixel
  106.         int samplesPerPixel = Math.round(
  107.                 pixelDuration * AUDIO_FORMAT.getSampleRate());
  108.        
  109.         //number of samples between career meander change
  110.         int careerPeriod = SAMPLE_RATE / CAREER_FREQUENCY;
  111.        
  112.         int bufferLength = (int)(samplesPerPixel * cols * rows);
  113.         byte[] buf = new byte[bufferLength];
  114.         int iPixel = 0; //current pixel of the IMAGE
  115.         int careerValue = -1; //current career meander state (+1 or -1)
  116.        
  117.         int pixelCounter = samplesPerPixel;
  118.         int careerCounter = careerPeriod;
  119.         for (int i = 0; i < bufferLength; i++) {
  120.             buf[i] = (byte)(VOLUME * careerValue * image[iPixel]);
  121.             if (--pixelCounter == 0) {
  122.                 pixelCounter = samplesPerPixel;
  123.                 iPixel++;
  124.                 careerValue = -careerValue;
  125.             } else if (--careerCounter == 0) {
  126.                 careerValue = -careerValue;
  127.                 careerCounter = careerPeriod;
  128.             }
  129.            
  130.         }
  131.         return buf;
  132.     }
  133.  
  134.     /**
  135.      * Outputs the given audio <tt>samples</tt> to sound card.
  136.      * Does not return until playing is done.
  137.      * @param samples         audio samples to play, representing
  138.      *                        one image frame (in {@link #AUDIO_FORMAT}).
  139.      * @param loopCount       number of times to repeat the samples
  140.      * @throws LineUnavailableException
  141.      * @throws InterruptedException
  142.      */
  143.     protected static void playFrame(byte[] samples, int loopCount)
  144.             throws LineUnavailableException, InterruptedException {
  145.         Clip clickClip = AudioSystem.getClip();
  146.         clickClip.open(AUDIO_FORMAT, samples, 0, samples.length);
  147.         try {
  148.             System.out.print("Playing... ");
  149.             clickClip.setFramePosition(0);
  150.             clickClip.loop(loopCount);
  151.             clickClip.drain();
  152.             //sleep until all the sound is played
  153.             Thread.sleep((1000 * samples.length/SAMPLE_RATE) * loopCount);
  154.         } finally {
  155.             clickClip.close();
  156.             System.out.println("Done");
  157.         }        
  158.     }
  159.  
  160.     /**
  161.      * Saves raw audio samples (in {@link #AUDIO_FORMAT} format) to a wave file.
  162.      * @param samples   audio samples to save
  163.      * @param fileName  fully specified output file name
  164.      * @throws IOException
  165.      */
  166.     protected static void saveToWav(byte[] samples, String fileName) throws IOException {
  167.         AudioInputStream in = new AudioInputStream(
  168.                 new ByteArrayInputStream(samples),
  169.                 AUDIO_FORMAT, samples.length/AUDIO_FORMAT.getFrameSize());
  170.         try {
  171.             BufferedOutputStream out = new BufferedOutputStream(
  172.                     new FileOutputStream(fileName));
  173.             try {
  174.                 WaveFileWriter writer = new WaveFileWriter();
  175.                 writer.write(in, AudioFileFormat.Type.WAVE, out);
  176.             } finally {
  177.                 out.close();
  178.             }
  179.         } finally {
  180.             in.close();
  181.         }
  182.     }
  183.  
  184. }
  185.  
  186.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement