SafeDispatch/AppServer/VoiceRecording.cs

411 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SafeMobileLib;
using System.IO;
namespace AppServer
{
class VoiceRecording
{
private string ip;
private int port;
private UdpMulticast udp4VoiceRecv;
private bool isRecording;
public bool IsRecording
{
get { return isRecording; }
set { isRecording = value; }
}
private MemoryStream recStream;
private string fileDir;
System.Timers.Timer backUPTimer;
private DBrecordingsManager DBrec;
private int gwID;
private int radioGWid;
private int typeSD;
private Int32 callType;
private UdpMulticast udp_multi;
private int sampleRate = 8000;
private int bitdepth = 16;
public int? dispatcher_id;
public int? subs_imei;
private int? group_cpsid;
private DateTime dtStart;
public VoiceRecording(string ip, int voicePort, int gwID, int radiogwID, int? dispatcherId, int? subs_imei, int? group_cpsid, int typeSD, Int32 callType, UdpMulticast udp_multi, int sampleRate, int bitdepth)
{
this.ip = ip;
this.port = voicePort;
this.gwID = gwID;
this.radioGWid = radiogwID;
this.dispatcher_id = dispatcherId;
this.subs_imei = subs_imei;
this.group_cpsid = group_cpsid;
this.typeSD = typeSD;
this.callType = callType;
this.udp_multi = udp_multi;
this.sampleRate = sampleRate;
this.bitdepth = bitdepth;
fileDir = @"recordings";
DirectoryInfo dir = new DirectoryInfo(fileDir);
if (!Directory.Exists(fileDir))
{
dir.Create();
}
DBrec = new DBrecordingsManager(Program.cfg.DB_IP, Program.cfg.DB_schema, Program.cfg.DB_user, Program.cfg.DB_passwd, Program.cfg.DB_port);
SM.Debug("Starting voice recording for " + ip);
udp4VoiceRecv = new UdpMulticast(ip, port);
udp4VoiceRecv.OnNewDataRecv += new UdpMulticast.newData4Send(udp4VoiceRecv_OnNewDataRecv);
backUPTimer = new System.Timers.Timer();
backUPTimer.Interval = 60000;
backUPTimer.Elapsed += new System.Timers.ElapsedEventHandler(backUPTimer_Elapsed);
}
void backUPTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
SM.Debug("backup timer expired(60sec) ... force stoping voice recording");
Stop();
}
void udp4VoiceRecv_OnNewDataRecv(byte[] data, int dataLen)
{
if (isRecording)
{
Console.WriteLine("datalen="+dataLen);
if (dataLen > 0)
{
recStream.Write(data, 0, dataLen);
}
}
}
public void Start()
{
udp4VoiceRecv.StartListen_ThreadPool();
recStream = new MemoryStream();
isRecording = true;
backUPTimer.Enabled = true;
dtStart = DateTime.Now;
}
private string test;
public void Stop()
{
try
{
backUPTimer.Enabled = false;
udp4VoiceRecv.StopListen();
SM.Debug("Recording stoped... dumping memory stream in to file; len=" + recStream.ToArray().Length);
if (recStream.ToArray().Length == 0)
{
SM.Debug("Nothing to write. Returning");
return;
}
if (MainForm.recordings == 0)
{
SM.Debug("No recordings license. Returning");
return;
}
Int32 call_type = GetCallType(); // 0-private 1-group 2-all call 3-users voice call from dispacher
// 4-private 5 -group 6 -all call
string ending = ".wav";
string endRepeater = ".amb";
//format the name of the recording
string filename = FormatFileName();
filename = filename.Replace(' ', '_');
//if we got some data save it 2 file
if (recStream.Length > 0)
{
string fileName = fileDir + "/" + filename + ending;
string fileNameDB = fileName;
if ((MulticastListener.GatewayList[gwID] != null) && ((Boolean)MulticastListener.GatewayList[gwID]))
fileName = fileDir + "/" + filename + endRepeater;
using (FileStream fs1 = new FileStream(fileName, System.IO.FileMode.Create))
{
if (!((MulticastListener.GatewayList[gwID] != null) && ((Boolean)MulticastListener.GatewayList[gwID])))
{
WriteHeader(fs1, recStream.ToArray().Length, 1, sampleRate, bitdepth);
}
System.IO.BinaryWriter bw = new BinaryWriter(fs1);
bw.Write(recStream.ToArray());
bw.Close();
}
// trigger event when a recording was received from the repeater
if ((MulticastListener.GatewayList[gwID] != null) && ((Boolean)MulticastListener.GatewayList[gwID]))
OnRecordingFileWritteen(fileName);
// add to db
Recording rec = new Recording(dtStart.GetSecondsLocalFromDT() * 1000000 + DateTime.Now.Millisecond * 1000, dtStart.GetSecondsLocalFromDT(), DateTime.Now.GetSecondsLocalFromDT(), dtStart, DateTime.Now, fileNameDB, subs_imei, gwID, radioGWid, typeSD, call_type, group_cpsid, dispatcher_id);
DBrec.addRecording(rec);
test = $"#155#{rec.id}#{rec.hddLocation}#{rec.gwID}#{rec.radioGWID}#{rec.group_cpsId}#{rec.subs_imei}#{rec.startTime}#{rec.endTime}#{rec.typeSD}#{rec.calltype}#{rec.dispatcher_id}#";
byte[] dataToSend = Utils.Convert_text_For_multicast("#0.0" + test);
MainForm.udp.Send(dataToSend, dataToSend.Length);
}
}
catch (Exception ex)
{
SM.Debug(ex.ToString());
}
finally
{
backUPTimer.Close();
recStream.Flush();
isRecording = false;
}
}
private int GetCallType()
{
int call_type = 0;
if (typeSD == 0)
{
if (callType == 162)
call_type = 7;
else
{
switch (callType)
{
case 101 /*AllCall*/:
call_type = 6;
break;
case 102 /* Private call */:
call_type = 4;
break;
case 103 /* Group call */:
call_type = 5;
break;
}
}
}
if (typeSD == 1)
{
switch (callType)
{
case 201:
call_type = 3;
break;
case 101:
call_type = 2;
break;
case 102:
call_type = 0;
break;
case 103:
call_type = 1;
break;
}
}
return call_type;
}
private string FormatDispatcherRadioFileName()
{
string filename = string.Empty;
string tmp = "";
if (typeSD == 1)
{
switch (callType)
{
case 201:
tmp = "";
if (MulticastListener.UserList[radioGWid] != null)
tmp = "_" + MulticastListener.UserList[radioGWid] + "_";
else
tmp = "_UserID(" + radioGWid.ToString() + ")_";
if (MulticastListener.UserList[dispatcher_id] != null)
filename = MulticastListener.UserList[dispatcher_id] + "_CALL_USER_TO" + tmp + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename = "UserID(" + dispatcher_id.ToString() + ")_CALL_USER_TO" + tmp + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
break;
case 101: // dispatcher - radio (all call)
if (MulticastListener.UserList[dispatcher_id] != null)
filename = MulticastListener.UserList[dispatcher_id] + "_ALLCALL_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename = "UserID(" + dispatcher_id.ToString() + ")_ALLCALL_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
break;
case 102: // dispatcher - radio (private call)
tmp = "";
if (MulticastListener.VehicleList[subs_imei.ToString()] != null)
tmp = "_" + MulticastListener.VehicleList[subs_imei.ToString()] + "(" + subs_imei.ToString() + ")_";
else
tmp = "_RadioID(" + subs_imei.ToString() + ")_";
if (MulticastListener.UserList[dispatcher_id] != null)
filename = MulticastListener.UserList[dispatcher_id] + "_PRIVATE_CALL_TO" + tmp + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename = "UserID(" + dispatcher_id.ToString() + ")_PRIVATE_CALL_TO" + tmp + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
break;
case 103: // dispatcher - radio (group call)
if (MulticastListener.UserList[(int)dispatcher_id] != null)
filename = MulticastListener.UserList[(int)dispatcher_id] + "_GROUP_CALL_" + dispatcher_id.ToString() + "_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename = "UserID(" + dispatcher_id.ToString() + ")_GROUP_CALL_" + group_cpsid.ToString() + "_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
break;
}
}
return filename.Trim();
}
private string FormatRadioDispatcherFileName()
{
string filename = string.Empty;
if (typeSD == 0)
{
if (callType == 162) // Remote monitor
{
if (MulticastListener.VehicleList[subs_imei.ToString()] != null)
filename = "Remote monitor " + MulticastListener.VehicleList[subs_imei.ToString()] + "(" + subs_imei.ToString() + ")" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename = "Remote monitor RadioID(" + subs_imei.ToString() + ") " + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
}
else
{
if (callType == 103)
{
if (MulticastListener.VehicleList[subs_imei.ToString()] != null)
filename = MulticastListener.VehicleList[subs_imei.ToString()] + "(" + subs_imei.ToString() + ")" + "_DO_GROUP_CALL_ID_" + group_cpsid.ToString() + "_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename = "RadioID(" + subs_imei.ToString() + ")_DO_GROUP_CALL_ID_" + group_cpsid.ToString() + "_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
}
else if (callType == 102) // radio - dispatcher ( private call)
{
if (MulticastListener.VehicleList[subs_imei.ToString()] != null)
filename = MulticastListener.VehicleList[subs_imei.ToString()] + "(" + subs_imei.ToString() + ")" + "_DO_A_PRIVATE_CALL_";
else
filename = "RadioID(" + subs_imei.ToString() + ")_DO_A_PRIVATE_CALL_";
if (MulticastListener.VehicleList[dispatcher_id.ToString()] != null)
filename += MulticastListener.VehicleList[dispatcher_id.ToString()] + "(" + dispatcher_id.ToString() + ")" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename += "RadioID(" + dispatcher_id.ToString() + ")" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
}
else if (callType == 101) // radio - dispatcher ( all call)
{
if (MulticastListener.VehicleList[subs_imei.ToString()] != null)
filename = MulticastListener.VehicleList[subs_imei.ToString()] + "(" + subs_imei.ToString() + ")" + "_DO_ALL_CALL_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
else
filename = "RadioID(" + subs_imei.ToString() + ")_DO_ALL_CALL_" + DateTime.Now.ToString("dd_MMM_yy_HH_mm_ss");
}
}
}
return filename.Trim();
}
private string FormatFileName()
{
if (typeSD == 0)
return FormatRadioDispatcherFileName();
return FormatDispatcherRadioFileName();
}
public static void WriteHeader(
System.IO.Stream targetStream,
int byteStreamSize,
int channelCount,
int sampleRate,
int bitdepth)
{
bool isFloatingPoint = false;
targetStream.Position = 0;
// RIFF header.
// Chunk ID.
targetStream.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4);
// Chunk size.
targetStream.Write(BitConverter.GetBytes(((bitdepth / 8) * byteStreamSize) + 36), 0, 4);
// Format.
targetStream.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4);
// Sub-chunk 1.
// Sub-chunk 1 ID.
targetStream.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4);
// Sub-chunk 1 size.
targetStream.Write(BitConverter.GetBytes(16), 0, 4);
// Audio format (floating point (3) or PCM (1)). Any other format indicates compression.
targetStream.Write(BitConverter.GetBytes((ushort)(isFloatingPoint ? 3 : 1)), 0, 2);
// Channels.
targetStream.Write(BitConverter.GetBytes(channelCount), 0, 2);
// Sample rate.
targetStream.Write(BitConverter.GetBytes(sampleRate), 0, 4);
// Bytes rate.
targetStream.Write(BitConverter.GetBytes(sampleRate * channelCount * (bitdepth / 8)), 0, 4);
// Block align.
targetStream.Write(BitConverter.GetBytes((ushort)channelCount * (bitdepth / 8)), 0, 2);
// Bits per sample.
targetStream.Write(BitConverter.GetBytes(bitdepth), 0, 2);
// Sub-chunk 2.
// Sub-chunk 2 ID.
targetStream.Write(Encoding.ASCII.GetBytes("data"), 0, 4);
// Sub-chunk 2 size.
targetStream.Write(BitConverter.GetBytes((bitdepth / 8) * byteStreamSize), 0, 4);
}
public delegate void RecordingFileWritteenDEl(string filePath);
public event RecordingFileWritteenDEl OnRecordingFileWritteen;
}
}