我尝试将音频从移动麦克风保存到Tmemorystream,然后使用以下功能将其转换为十六进制:
function StreamToHexStr(AStream: TStream): string;
const
HexArr: array[0..15] of char =
('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
var
AByte: Byte;
i: Integer;
begin
SetLength(Result, AStream.Size * 2);
AStream.Position := 0;
for i := 0 to AStream.Size - 1 do
begin
AStream.ReadBuffer(AByte, SizeOf(AByte));
Result[i * 2 + 1] := HexArr[AByte shr 4];
Result[i * 2 + 2] := HexArr[AByte and $0F];
end;
end;
输出为十六进制字符串
将其转移到第二台设备后,我必须将十六进制代码更改为Tmemorystream并使用此功能进行播放:
Stream := TMemoryStream.Create;
try
Writer := TBinaryWriter.Create(Stream);
try
Writer.Write(TEncoding.UTF8.GetBytes(ReciavedSTR));
finally
Writer.Free;
end;
Stream.SaveToFile( TPath.GetSharedMoviesPath()+'/record2.mp3' );
但是record2.mp3
无法播放,它仅包含转换后的十六进制字符串
我的代码有什么问题?
当我使用此代码将记录的流保存到文件中时进行简单测试
FOutputStream.SaveToFile( TPath.GetSharedMoviesPath()+'/record.mp3' );
运作良好。
更新项目概念:
硬件发送器在串行端口上从手机获取406十六进制字符并将其传输到第二个设备,然后接收器将十六进制字符串传递到第二个手机,第二个电话必须加入字符串并将其转换为可听见的声音。 / p>
base64的示例输出,用于流传输并将流保存到文件
答案 0 :(得分:3)
首先,让我回答您的第一个问题
您要转换为base16的代码是正确的,这是一个基本相等的版本:
function StreamToHexStr(const AStream: TStream): String;
const
cMap : array[0..15] of Char = (
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F');
var
lData: Byte;
lPos: Integer;
begin
Setlength(Result, AStream.Size * 2);
AStream.Position := 0;
lPos := Low(Result);
while AStream.ReadData(lData) = sizeof(lData) do begin
Result[lPos] := cMap[lData shr 4];
Result[lPos + 1] := cMap[lData and $0F];
Inc(lPos, 2);
end;
end;
要将字符串转换回流,请尝试以下操作:
procedure HexStrToStream(const AString: String; AStream: TStream);
const
// Mapping vom ASCII-Code to value
cMap: array['0'..'F'] of Byte = (
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // $30..$39 / '0'..'9'
100, 100, 100, 100, 100, 100, 100, // $3A..$40
10, 11, 12, 13, 14, 15); // $41..$46 / 'A'..'F'
var
lPos: Integer;
begin
lPos := Low(AString);
while lPos < High(AString) do begin
AStream.WriteData(UInt8(cMap[AString[lPos]] shl 4 + cMap[AString[lPos + 1]]));
Inc(lPos, 2);
end;
end;
只需使用以下代码即可:
Base16String := StreamToHexStr(MP3Stream);
在发送者和接收者上执行:
lRecvStream := TMemoryStream.Create();
try
HexStrToStream(Base16RecvString, RecvStream);
lRecvStream.SaveToFile('Record.mp3');
finally
lRecvStream.Free();
end;
只需在发送端使用TMemoryStream,即可:
lString := TNetEncoding.Base64.EncodeBytesToString(lInStream.Memory, lInStream.Size);
在接收端,您使用TBytesStream(它是TMemoryStream的后代):
lRecvStream := TBytesStream.Create(TNetEncoding.Base64.DecodeStringToBytes(lString));
try
lRecvStream.SaveToFile('Record.mp3');
finally
lRecvStream.Free();
end;
在数据传输期间,某些字节可能会更改或丢失。有时将不会接收到整个数据包。根据您的要求,您的应用程序可能需要一些保护以防止此类错误。