using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace TTS.Struct
{
///
/// 生成语音结果
///
public sealed partial class SherpaOnnxGeneratedAudioResult : IDisposable
{
public const string Filename = "sherpa-onnx-c-api";
///
/// 销毁非托管内存
///
///
[DllImport(Filename)]
private static extern void SherpaOnnxDestroyOfflineTtsGeneratedAudio(IntPtr ttsGenerateIntptr);
[DllImport(Filename)]
private static extern int SherpaOnnxWriteWave(IntPtr q, int n, int sample_rate, string filename);
///
/// 音频数据比特
///
public const int AudioDataBit = 16;
///
/// 单通道
///
public const int Channels = 1;
///
/// 原生句柄
///
internal IntPtr thisHandle;
internal readonly IntPtr audioData;
internal readonly int dataSize;
///
/// 采样率
///
public readonly int sample_rate;
///
/// 音频数据指针
///
public IntPtr AudioDataIntPtr => audioData;
///
/// 数据的大小
///
public unsafe int AudioDataLength
{
get
{
return dataSize;
//float* buffer = (float*)audioData;
//while (*buffer != 0)
// ++buffer;
//return (int)(buffer - (float*)audioData);
}
}
///
/// 获得音频数据 float[]
/// 这个内部创建一个数组
///
public unsafe float[] AudioFloatData
{
get
{
int length = AudioDataLength;
float[] floatAudioData = new float[length];
Marshal.Copy(audioData, floatAudioData, 0, floatAudioData.Length);
return floatAudioData;
}
}
///
/// 获得音频数据 byte[]
/// 这个内部创建一个数组
///
public byte[] AudioByteData
{
get
{
byte[] bytes = new byte[AudioDataLength * 2];
ReadData(bytes, 0);
return bytes;
}
}
internal SherpaOnnxGeneratedAudioResult(IntPtr intPtr, SherpaOnnxGeneratedAudio sherpaOnnx)
{
this.thisHandle = intPtr;
this.audioData = sherpaOnnx.audioData;
this.dataSize = sherpaOnnx.dataSize;
this.sample_rate = sherpaOnnx.sample_rate;
}
~SherpaOnnxGeneratedAudioResult()
{
Dispose();
}
///
/// 读取数据
/// 没有垃圾产生,自己传递数组进来
///
/// 数组
/// 数组那个位置写入
/// 写入了多少个
public int ReadData(float[] audioFloats, int offset)
{
int length = AudioDataLength;
int c = audioFloats.Length - offset;
length = c >= length ? length : c;
Marshal.Copy(audioData, audioFloats, offset, length);
return length;
}
///
/// 读取数据
/// 这个内部转换成byte[] 音频数组
/// 没有垃圾产生,自己传递数组进来
///
/// 数组,这个长度需要是AudioDataLength*2大小
/// 数组那个位置写入
/// 写入了多少个
public int ReadData(byte[] audioFloats, int offset)
{
//因为是16bit存储音频数据,所以float会转换成两个字节存储
var audiodata = AudioFloatData;
int length = audiodata.Length * 2;
int c = audioFloats.Length - offset;
c = c % 2 == 0 ? c : c - 1;
length = c >= length ? length : c;
int p = length / 2;
for (int i = 0; i < p; i++)
{
short value = (short)(audiodata[i] * short.MaxValue);
audioFloats[offset++] = (byte)value;
audioFloats[offset++] = (byte)(value >> 8);
}
return length;
}
///
/// 写入WAV音频数据
///
///
///
public bool WriteWAVFile(string filename)
{
return 1 == SherpaOnnxWriteWave(audioData, this.dataSize, this.sample_rate, filename);
}
public void Dispose()
{
if (this.thisHandle != IntPtr.Zero)
{
SherpaOnnxDestroyOfflineTtsGeneratedAudio(this.thisHandle);
GC.SuppressFinalize(this);
this.thisHandle = IntPtr.Zero;
}
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct SherpaOnnxGeneratedAudio
{
internal readonly IntPtr audioData;
internal readonly int dataSize;
///
/// 采样率
///
public readonly int sample_rate;
}
}