audiotemplate.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: audiotemplate.c 543 2006-01-07 22:06:24Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common/common.h"
  24. #include "audiotemplate.h"
  25. #include <math.h>
  26. #define BUFFERSIZE 4096
  27. typedef struct audio_template
  28. {
  29. codec Codec;
  30. int16_t* Buffer;
  31. int16_t Sin[1024];
  32. tick_t LastTime;
  33. int PhaseLeft;
  34. int PhaseRight;
  35. } audio_template;
  36. static int Process( audio_template* p, const packet* Packet, const flowstate* State )
  37. {
  38. int i;
  39. int Size;
  40. // you can return ERR_NEED_MORE_DATA if data is not enough for decode output packet
  41. // but this means the decoder has to buffer the input
  42. // if (Packet)
  43. //   AddBuffer(Packet)
  44. // if (Buffer.Length < 1024)
  45. //   return ERR_NEED_MORE_DATA;
  46. if (!Packet)
  47. return ERR_NEED_MORE_DATA;
  48. if (p->LastTime<0 && Packet->RefTime>=0)
  49. p->LastTime = Packet->RefTime;
  50. // this is fake audio codec, so we try to generate 
  51. // as much data to be in sync with RefTime
  52. Size = Scale(Packet->RefTime - p->LastTime,44100,TICKSPERSEC);
  53. if (Size <= 0)
  54. return ERR_NONE;
  55. if (Size > BUFFERSIZE)
  56. Size = BUFFERSIZE;
  57. p->Codec.Packet.RefTime = Packet->RefTime; 
  58. p->Codec.Packet.Data[0] = p->Buffer;
  59. p->Codec.Packet.Length = Size*2*sizeof(int16_t);
  60. if (p->LastTime >= 0)
  61. p->LastTime += Scale(Size,TICKSPERSEC,44100);
  62. for (i=0;i<Size;++i)
  63. {
  64. p->Buffer[2*i] = p->Sin[p->PhaseLeft & 1023];
  65. p->Buffer[2*i+1] = p->Sin[p->PhaseRight & 1023];
  66. p->PhaseLeft += 4;
  67. p->PhaseRight += 7;
  68. }
  69. return ERR_NONE;
  70. }
  71. // empty buffers and do what ever needed after seek
  72. static int Flush( audio_template* p )
  73. {
  74. p->LastTime = -1;
  75. p->PhaseLeft = 0;
  76. p->PhaseRight = 0;
  77. return ERR_NONE;
  78. }
  79. static int UpdateInput( audio_template* p )
  80. {
  81. free(p->Buffer);
  82. p->Buffer = NULL;
  83. if (p->Codec.In.Format.Type == PACKET_AUDIO)
  84. {
  85. PacketFormatClear(&p->Codec.Out.Format);
  86. p->Codec.Out.Format.Type = PACKET_AUDIO;
  87. p->Codec.Out.Format.Format.Audio.Format = AUDIOFMT_PCM;
  88. p->Codec.Out.Format.Format.Audio.Bits = 16;
  89. p->Codec.Out.Format.Format.Audio.FracBits = 15;
  90. p->Codec.Out.Format.Format.Audio.Channels = 2;
  91. p->Codec.Out.Format.Format.Audio.SampleRate = 44100;
  92. p->Buffer = (int16_t*) malloc(BUFFERSIZE*2*sizeof(int16_t));
  93. if (!p->Buffer)
  94. return ERR_OUT_OF_MEMORY;
  95. }
  96. return ERR_NONE;
  97. }
  98. static int Create( audio_template* p )
  99. {
  100. int i;
  101. p->Codec.Process = (packetprocess)Process;
  102. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  103. p->Codec.Flush = (nodefunc)Flush;
  104. for (i=0;i<1024;++i)
  105. p->Sin[i] = (int16_t)(4096*sin(2*M_PI*i/1024));
  106. return ERR_NONE;
  107. }
  108. static const nodedef Template =
  109. {
  110. sizeof(audio_template),
  111. AUDIO_TEMPLATE_ID,
  112. CODEC_CLASS,
  113. PRI_DEFAULT+10, // use higher priorty as defualt MP3 codec so this example can override it
  114. (nodecreate)Create,
  115. NULL,
  116. };
  117. void Audio_Init()
  118. {
  119. StringAdd(1,AUDIO_TEMPLATE_ID,NODE_NAME,T("Audio template codec"));
  120. StringAdd(1,AUDIO_TEMPLATE_ID,NODE_CONTENTTYPE,T("acodec/0x0055"));
  121. NodeRegisterClass(&Template);
  122. }
  123. void Audio_Done()
  124. {
  125. NodeUnRegisterClass(AUDIO_TEMPLATE_ID);
  126. }