From aryx, 5 Years ago, written in Java.
Embed
  1. /**
  2.  * Perifériák és multimédia eszközök - Morse program.
  3.  * 6. feladat - Morse kódolás
  4.  *
  5.  * A program PUBLIC DOMAIN. A beadás után a forráskód nyilvánosan elérhetővé
  6.  * válik a potvizs.ga és a gotvizs.ga weboldalakról. A Public Domain licensz
  7.  * a program könyvtárában megtalálható a LICENSE.TXT fájlban.
  8.  *
  9.  * @author Tóth Patrik (aryx, ZLIMO5) <[email protected]>
  10.  * @version 1.0
  11.  */
  12. package morse;
  13.  
  14. import java.io.File;
  15. import java.io.IOException;
  16. import java.io.RandomAccessFile;
  17.  
  18. /**
  19.  *
  20.  * @author aryx
  21.  */
  22. public class Morse {
  23.     static String fileNameString;
  24.     static File file;
  25.     static String filePath;
  26.  
  27.     static RandomAccessFile raw;
  28.  
  29.     static int byteCount = 0;
  30.  
  31.     // kimenő wav fájl beállítása
  32.     static float freq;
  33.     static int sRate = 44100;
  34.     static int bitDepth = 16;
  35.     static int nChannels = 1;
  36.     static float dur;
  37.  
  38.     static float changeRate;
  39.  
  40.     static String message;
  41.    
  42.     /**
  43.     *
  44.     * Főfüggvény
  45.     *
  46.     * @author aryx, jaket
  47.     * @param args    A program paraméterei
  48.     */
  49.     public static void main(String[] args)
  50.     {
  51.        
  52.         System.out.println("Morse kod generalo program :: v1.0");
  53.         System.out.println("Toth Patrik <[email protected]>\n");
  54.        
  55.         if (args.length == 0) {
  56.             System.out.println("Segitseghez add ki a --help parametert!");
  57.             return;
  58.         }
  59.         if (args[0].equals("--help")) {
  60.             System.out.println("java -jar morse.jar 0.2 \"sos segitsenek\" sos.wav");
  61.             System.out.println("  - 1. param: egy egyseg idotartama (mp)");
  62.             System.out.println("  - 2. param: a kodolando szoveg");
  63.             System.out.println("  - 3. param: kimeno WAV fajl neve");
  64.             return;
  65.         }
  66.         if (args.length == 1 || args.length == 2) {
  67.             System.out.println("Segitseghez add ki a --help parametert!");
  68.             return;
  69.         }
  70.        
  71.         System.out.println("Egyseg hossza: " + args[0] + " s");
  72.         System.out.println("       Uzenet: " + args[1]);
  73.         System.out.println("      Kimenet: " + args[2]+"\n");
  74.        
  75.         System.out.println("Generalas folyamatban...");
  76.         long startTime = System.nanoTime();
  77.        
  78.         freq = 990; // Hz
  79.         changeRate = (float)((2.0 * Math.PI * freq) / sRate); // szinuszjel alapját adó szám (ciklusban lesz növelve)
  80.  
  81.         dur = Float.parseFloat(args[0]); // egy egység időtartama, 1. paraméter
  82.        
  83.         message = (String)args[1]; // üzenet, 2. paraméter
  84.         //message = message.replace("-", " ");
  85.         fileNameString = (String)args[2]; // fájlnév, 3. paraméter
  86.         file = new File(fileNameString);
  87.         filePath = file.getAbsolutePath();
  88.  
  89.         // Fájl megnyitása, RIFF header kiírása
  90.         // A kód eredete: https://stackoverflow.com/questions/40209335/how-to-generate-a-wav-file-with-a-sinusoidal-wave-and-user-defined-duration-and
  91.         try
  92.         {
  93.             raw = new RandomAccessFile(filePath, "rw");
  94.             raw.setLength(0); // Set file length to 0, to prevent unexpected behavior in case the file already existed
  95.             raw.writeBytes("RIFF");
  96.             raw.writeInt(0); // Final file size not known yet, write 0. This is = sample count + 36 bytes from header.
  97.             raw.writeBytes("WAVE");
  98.             raw.writeBytes("fmt ");
  99.             raw.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
  100.             raw.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
  101.             raw.writeShort(Short.reverseBytes((short)nChannels));// Number of channels, 1 for mono, 2 for stereo
  102.             raw.writeInt(Integer.reverseBytes(sRate)); // Sample rate
  103.             raw.writeInt(Integer.reverseBytes(sRate*bitDepth*nChannels/8)); // Byte rate, SampleRate*NumberOfChannels*bitDepth/8
  104.             raw.writeShort(Short.reverseBytes((short)(nChannels*bitDepth/8))); // Block align, NumberOfChannels*bitDepth/8
  105.             raw.writeShort(Short.reverseBytes((short)bitDepth)); // Bit Depth
  106.             raw.writeBytes("data");
  107.             raw.writeInt(0); // Data chunk size not known yet, write 0. This is = sample count.
  108.         }
  109.         catch(IOException e)
  110.         {
  111.             System.out.println("I/O hiba a fájl kezelése során! Van jogosultságod írni?");
  112.         }
  113.        
  114.         generateMorse(message, sRate, dur, changeRate);
  115.                
  116.         closeFile();
  117.         System.out.print("Sikeres generalas!");
  118.         float totalTime = System.nanoTime() - startTime;
  119.         System.out.print("A program " + totalTime/1000/1000/1000 + " mp ideig futott.\n");
  120.  
  121.     }
  122.    
  123.     /**
  124.     *
  125.     * Kiírja a nyitott WAV fájlba a megadott üzenetet morse kódolással
  126.     *
  127.     * @author aryx
  128.     * @param String message    Az átalakítandó üzenet szövege
  129.     * @param int sRate         Mintavételezési frekvencia
  130.     * @param float dur         Egy egység hossza másodpercben
  131.     * @param float changeRate  Szinuszjel amplitúdója
  132.     */
  133.     static void generateMorse(String message, int sRate, float dur, float changeRate) {
  134.        
  135.         // karakterenként végiglépünk az üzeneten
  136.        
  137.         message = message.toLowerCase();
  138.         for (char ch: message.toCharArray()) {
  139.             getMorseCode(ch, sRate, dur, changeRate);
  140.             writeCode(sRate, dur, 0, 3); // 3 egység szünet a betűk között
  141.         }
  142.        
  143.     }
  144.    
  145.     /**
  146.     *
  147.     * Adott karaktert, szünetet ír a nyitott WAV fájlba morse kódolással
  148.     *
  149.     * @author aryx
  150.     * @param char character     Az átalakítandó karakter
  151.     * @param int sRate          Mintavételezési frekvencia
  152.     * @param float dur          Egy egység hossza másodpercben
  153.     * @param float changeRate   Szinuszjel amplitúdója
  154.     */
  155.     static void getMorseCode(char character, int sRate, float dur, float changeRate) {
  156.         // TODO: tömbben tárolni a karaktereket kódját és abból kiolvasni
  157.         switch (character) {
  158.             case ' ':
  159.                 writeCode(sRate, dur, 0, 7);
  160.                 break;
  161.            
  162.             case 'a':
  163.                 writeCode(sRate, dur, changeRate, 1);
  164.                 writeCode(sRate, dur, changeRate, 3);
  165.                 break;
  166.            
  167.             case 'b':
  168.                 writeCode(sRate, dur, changeRate, 3);
  169.                 writeCode(sRate, dur, changeRate, 1);
  170.                 writeCode(sRate, dur, changeRate, 1);
  171.                 writeCode(sRate, dur, changeRate, 1);
  172.                 break;
  173.            
  174.             case 'c':
  175.                 writeCode(sRate, dur, changeRate, 3);
  176.                 writeCode(sRate, dur, changeRate, 1);
  177.                 writeCode(sRate, dur, changeRate, 3);
  178.                 writeCode(sRate, dur, changeRate, 1);
  179.                 break;
  180.            
  181.             case 'd':
  182.                 writeCode(sRate, dur, changeRate, 3);
  183.                 writeCode(sRate, dur, changeRate, 1);
  184.                 writeCode(sRate, dur, changeRate, 1);
  185.                 break;
  186.            
  187.             case 'e':
  188.                 writeCode(sRate, dur, changeRate, 1);
  189.                 break;
  190.            
  191.             case 'f':
  192.                 writeCode(sRate, dur, changeRate, 1);
  193.                 writeCode(sRate, dur, changeRate, 1);
  194.                 writeCode(sRate, dur, changeRate, 3);
  195.                 writeCode(sRate, dur, changeRate, 1);
  196.                 break;
  197.            
  198.             case 'g':
  199.                 writeCode(sRate, dur, changeRate, 3);
  200.                 writeCode(sRate, dur, changeRate, 3);
  201.                 writeCode(sRate, dur, changeRate, 1);
  202.                 break;
  203.            
  204.             case 'h':
  205.                 writeCode(sRate, dur, changeRate, 1);
  206.                 writeCode(sRate, dur, changeRate, 1);
  207.                 writeCode(sRate, dur, changeRate, 1);
  208.                 writeCode(sRate, dur, changeRate, 1);
  209.                 break;
  210.            
  211.             case 'i':
  212.                 writeCode(sRate, dur, changeRate, 1);
  213.                 writeCode(sRate, dur, changeRate, 1);
  214.                 break;
  215.            
  216.             case 'j':
  217.                 writeCode(sRate, dur, changeRate, 1);
  218.                 writeCode(sRate, dur, changeRate, 3);
  219.                 writeCode(sRate, dur, changeRate, 3);
  220.                 writeCode(sRate, dur, changeRate, 3);
  221.                 break;
  222.            
  223.             case 'k':
  224.                 writeCode(sRate, dur, changeRate, 3);
  225.                 writeCode(sRate, dur, changeRate, 1);
  226.                 writeCode(sRate, dur, changeRate, 3);
  227.                 break;
  228.            
  229.             case 'l':
  230.                 writeCode(sRate, dur, changeRate, 1);
  231.                 writeCode(sRate, dur, changeRate, 3);
  232.                 writeCode(sRate, dur, changeRate, 1);
  233.                 writeCode(sRate, dur, changeRate, 1);
  234.                 break;
  235.            
  236.             case 'm':
  237.                 writeCode(sRate, dur, changeRate, 3);
  238.                 writeCode(sRate, dur, changeRate, 3);
  239.                 break;
  240.            
  241.             case 'n':
  242.                 writeCode(sRate, dur, changeRate, 3);
  243.                 writeCode(sRate, dur, changeRate, 1);
  244.                 break;
  245.            
  246.             case 'o':
  247.                 writeCode(sRate, dur, changeRate, 3);
  248.                 writeCode(sRate, dur, changeRate, 3);
  249.                 writeCode(sRate, dur, changeRate, 3);
  250.                 break;
  251.            
  252.             case 'p':
  253.                 writeCode(sRate, dur, changeRate, 1);
  254.                 writeCode(sRate, dur, changeRate, 3);
  255.                 writeCode(sRate, dur, changeRate, 3);
  256.                 writeCode(sRate, dur, changeRate, 1);
  257.                 break;
  258.            
  259.             case 'q':
  260.                 writeCode(sRate, dur, changeRate, 3);
  261.                 writeCode(sRate, dur, changeRate, 3);
  262.                 writeCode(sRate, dur, changeRate, 1);
  263.                 writeCode(sRate, dur, changeRate, 3);
  264.                 break;
  265.            
  266.             case 'r':
  267.                 writeCode(sRate, dur, changeRate, 1);
  268.                 writeCode(sRate, dur, changeRate, 3);
  269.                 writeCode(sRate, dur, changeRate, 1);
  270.                 break;
  271.            
  272.             case 's':
  273.                 writeCode(sRate, dur, changeRate, 1);
  274.                 writeCode(sRate, dur, changeRate, 1);
  275.                 writeCode(sRate, dur, changeRate, 1);
  276.                 break;
  277.            
  278.             case 't':
  279.                 writeCode(sRate, dur, changeRate, 3);
  280.                 break;
  281.            
  282.             case 'u':
  283.                 writeCode(sRate, dur, changeRate, 1);
  284.                 writeCode(sRate, dur, changeRate, 1);
  285.                 writeCode(sRate, dur, changeRate, 3);
  286.                 break;
  287.            
  288.             case 'v':
  289.                 writeCode(sRate, dur, changeRate, 1);
  290.                 writeCode(sRate, dur, changeRate, 1);
  291.                 writeCode(sRate, dur, changeRate, 1);
  292.                 writeCode(sRate, dur, changeRate, 3);
  293.                 break;
  294.            
  295.             case 'w':
  296.                 writeCode(sRate, dur, changeRate, 1);
  297.                 writeCode(sRate, dur, changeRate, 3);
  298.                 writeCode(sRate, dur, changeRate, 3);
  299.                 break;
  300.            
  301.             case 'x':
  302.                 writeCode(sRate, dur, changeRate, 3);
  303.                 writeCode(sRate, dur, changeRate, 1);
  304.                 writeCode(sRate, dur, changeRate, 1);
  305.                 writeCode(sRate, dur, changeRate, 3);
  306.                 break;
  307.            
  308.             case 'y':
  309.                 writeCode(sRate, dur, changeRate, 3);
  310.                 writeCode(sRate, dur, changeRate, 1);
  311.                 writeCode(sRate, dur, changeRate, 3);
  312.                 writeCode(sRate, dur, changeRate, 3);
  313.                 break;
  314.            
  315.             case 'z':
  316.                 writeCode(sRate, dur, changeRate, 3);
  317.                 writeCode(sRate, dur, changeRate, 3);
  318.                 writeCode(sRate, dur, changeRate, 1);
  319.                 writeCode(sRate, dur, changeRate, 1);
  320.                 break;
  321.            
  322.             case '0':
  323.                 writeCode(sRate, dur, changeRate, 3);
  324.                 writeCode(sRate, dur, changeRate, 3);
  325.                 writeCode(sRate, dur, changeRate, 3);
  326.                 writeCode(sRate, dur, changeRate, 3);
  327.                 writeCode(sRate, dur, changeRate, 3);
  328.                 break;
  329.            
  330.             case '1':
  331.                 writeCode(sRate, dur, changeRate, 1);
  332.                 writeCode(sRate, dur, changeRate, 3);
  333.                 writeCode(sRate, dur, changeRate, 3);
  334.                 writeCode(sRate, dur, changeRate, 3);
  335.                 writeCode(sRate, dur, changeRate, 3);
  336.                 break;
  337.            
  338.             case '2':
  339.                 writeCode(sRate, dur, changeRate, 1);
  340.                 writeCode(sRate, dur, changeRate, 1);
  341.                 writeCode(sRate, dur, changeRate, 3);
  342.                 writeCode(sRate, dur, changeRate, 3);
  343.                 writeCode(sRate, dur, changeRate, 3);
  344.                 break;
  345.            
  346.             case '3':
  347.                 writeCode(sRate, dur, changeRate, 1);
  348.                 writeCode(sRate, dur, changeRate, 1);
  349.                 writeCode(sRate, dur, changeRate, 1);
  350.                 writeCode(sRate, dur, changeRate, 3);
  351.                 writeCode(sRate, dur, changeRate, 3);
  352.                 break;
  353.            
  354.             case '4':
  355.                 writeCode(sRate, dur, changeRate, 1);
  356.                 writeCode(sRate, dur, changeRate, 1);
  357.                 writeCode(sRate, dur, changeRate, 1);
  358.                 writeCode(sRate, dur, changeRate, 1);
  359.                 writeCode(sRate, dur, changeRate, 3);
  360.                 break;
  361.            
  362.             case '5':
  363.                 writeCode(sRate, dur, changeRate, 1);
  364.                 writeCode(sRate, dur, changeRate, 1);
  365.                 writeCode(sRate, dur, changeRate, 1);
  366.                 writeCode(sRate, dur, changeRate, 1);
  367.                 writeCode(sRate, dur, changeRate, 1);
  368.                 break;
  369.            
  370.             case '6':
  371.                 writeCode(sRate, dur, changeRate, 3);
  372.                 writeCode(sRate, dur, changeRate, 1);
  373.                 writeCode(sRate, dur, changeRate, 1);
  374.                 writeCode(sRate, dur, changeRate, 1);
  375.                 writeCode(sRate, dur, changeRate, 1);
  376.                 break;
  377.            
  378.             case '7':
  379.                 writeCode(sRate, dur, changeRate, 3);
  380.                 writeCode(sRate, dur, changeRate, 3);
  381.                 writeCode(sRate, dur, changeRate, 1);
  382.                 writeCode(sRate, dur, changeRate, 1);
  383.                 writeCode(sRate, dur, changeRate, 1);
  384.                 break;
  385.            
  386.             case '8':
  387.                 writeCode(sRate, dur, changeRate, 3);
  388.                 writeCode(sRate, dur, changeRate, 3);
  389.                 writeCode(sRate, dur, changeRate, 3);
  390.                 writeCode(sRate, dur, changeRate, 1);
  391.                 writeCode(sRate, dur, changeRate, 1);
  392.                 break;
  393.            
  394.             case '9':
  395.                 writeCode(sRate, dur, changeRate, 3);
  396.                 writeCode(sRate, dur, changeRate, 3);
  397.                 writeCode(sRate, dur, changeRate, 3);
  398.                 writeCode(sRate, dur, changeRate, 3);
  399.                 writeCode(sRate, dur, changeRate, 1);
  400.                 break;
  401.         }      
  402.     }
  403.    
  404.     /**
  405.     *
  406.     * Adott hosszú és amplitúdójú szinuszjelet ír a megadott mintavételezési
  407.     * frekvenciával a nyitott WAV fájlba. A morsekód hossza (egység) itt
  408.     * adható meg.
  409.     *
  410.     * @author aryx
  411.     * @param int sRate         Mintavételezési frekvencia
  412.     * @param float dur         Egy egység hossza másodpercben
  413.     * @param float changeRate  Szinuszjel amplitúdója
  414.     * @param int length        Morse kód hossza egységben
  415.     */
  416.     static void writeCode(int sRate, float dur, float changeRate, int length) {
  417.         for (int i = 0; i < sRate*dur*length; i++)
  418.         {
  419.             writeSample( (float)Math.sin( i * changeRate ) );
  420.         }
  421.         for (int i = 0; i < sRate*dur; i++)
  422.         {
  423.             writeSample(0);
  424.         }
  425.     }
  426.  
  427.     /**
  428.     *
  429.     * Egy minta írása a nyitott WAV fileba.
  430.     *
  431.     * @author aryx
  432.     * @param float floatValue  A minta értéke
  433.     */
  434.     static void writeSample(float floatValue)
  435.     {
  436.         try
  437.         {
  438.             char shortSample = (char)( (floatValue)*0x7FFF );
  439.             raw.writeShort(Character.reverseBytes(shortSample));
  440.             byteCount += 2;
  441.         }
  442.         catch(IOException e)
  443.         {
  444.             System.out.println("I/O hiba lépett fel írás során. Van jogosultságod írni?");
  445.         }
  446.     }
  447.  
  448.     /**
  449.     *
  450.     * Bezárja a korábban nyitott WAV fájlt.
  451.     *
  452.     * @author aryx
  453.     */
  454.     static void closeFile()
  455.     {
  456.         try
  457.         {
  458.             raw.seek(4); // Write size to RIFF header
  459.             raw.writeInt(Integer.reverseBytes(byteCount + 36));
  460.             raw.seek(40); // Write size to Subchunk2Size field
  461.             raw.writeInt(Integer.reverseBytes(byteCount));
  462.             raw.close();
  463.         }
  464.         catch(IOException e)
  465.         {
  466.             System.out.println("I/O hiba lépett fel írás során. Van jogosultságod írni?");
  467.         }
  468.     }
  469.    
  470. }